From patchwork Thu May 4 19:53:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 13231704 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 59AC8C7EE21 for ; Thu, 4 May 2023 19:53:58 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.530061.825336 (Exim 4.92) (envelope-from ) id 1puf1L-0003zZ-Nx; Thu, 04 May 2023 19:53:43 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 530061.825336; Thu, 04 May 2023 19:53:43 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf1L-0003zS-JB; Thu, 04 May 2023 19:53:43 +0000 Received: by outflank-mailman (input) for mailman id 530061; Thu, 04 May 2023 19:53:42 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf1K-0003xx-MF for xen-devel@lists.xenproject.org; Thu, 04 May 2023 19:53:42 +0000 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 5cb4c55b-eab5-11ed-8611-37d641c3527e; Thu, 04 May 2023 21:53:39 +0200 (CEST) Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-558-qVm4RSmtOvC22VNK6fWUTQ-1; Thu, 04 May 2023 15:53:34 -0400 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 50FFE101A550; Thu, 4 May 2023 19:53:33 +0000 (UTC) Received: from localhost (unknown [10.39.192.57]) by smtp.corp.redhat.com (Postfix) with ESMTP id 78E421410F29; Thu, 4 May 2023 19:53:32 +0000 (UTC) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 5cb4c55b-eab5-11ed-8611-37d641c3527e DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1683230018; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=7t7uQFODUsT7GUPKJzVAstWb4vuQdfLqZNy3S4rp+B4=; b=L1ntaQo24O9SYlpe8zmaJ8bo+st/9Q4rwHvj9Zrg8zQnW+ojLaaZQR/FR29jZveEx5Cilv QzWLdGbDJPbRHtkckNKB1ACx9X1I6FV57xGjT0oU3UCV3UF2JKazquhOytbUIQeTe1BrL6 F3A4stphdxrZNMpMl0U1dKu65r7kWLM= X-MC-Unique: qVm4RSmtOvC22VNK6fWUTQ-1 From: Stefan Hajnoczi To: qemu-devel@nongnu.org Cc: Ronnie Sahlberg , Aarushi Mehta , qemu-block@nongnu.org, Paul Durrant , Anthony Perard , Peter Lieven , Stefan Weil , Xie Yongji , Kevin Wolf , Paolo Bonzini , "Michael S. Tsirkin" , Leonardo Bras , Peter Xu , Hanna Reitz , Stefano Stabellini , Richard Henderson , David Woodhouse , Coiby Xu , Eduardo Habkost , Stefano Garzarella , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , Stefan Hajnoczi , Julia Suvorova , xen-devel@lists.xenproject.org, eesposit@redhat.com, Juan Quintela , "Richard W.M. Jones" , Fam Zheng , Marcel Apfelbaum Subject: [PATCH v5 01/21] block: Fix use after free in blockdev_mark_auto_del() Date: Thu, 4 May 2023 15:53:07 -0400 Message-Id: <20230504195327.695107-2-stefanha@redhat.com> In-Reply-To: <20230504195327.695107-1-stefanha@redhat.com> References: <20230504195327.695107-1-stefanha@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.7 From: Kevin Wolf job_cancel_locked() drops the job list lock temporarily and it may call aio_poll(). We must assume that the list has changed after this call. Also, with unlucky timing, it can end up freeing the job during job_completed_txn_abort_locked(), making the job pointer invalid, too. For both reasons, we can't just continue at block_job_next_locked(job). Instead, start at the head of the list again after job_cancel_locked() and skip those jobs that we already cancelled (or that are completing anyway). Signed-off-by: Kevin Wolf Reviewed-by: Stefan Hajnoczi Signed-off-by: Stefan Hajnoczi Message-Id: <20230503140142.474404-1-kwolf@redhat.com> --- blockdev.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/blockdev.c b/blockdev.c index d7b5c18f0a..2c1752a403 100644 --- a/blockdev.c +++ b/blockdev.c @@ -153,12 +153,22 @@ void blockdev_mark_auto_del(BlockBackend *blk) JOB_LOCK_GUARD(); - for (job = block_job_next_locked(NULL); job; - job = block_job_next_locked(job)) { - if (block_job_has_bdrv(job, blk_bs(blk))) { + do { + job = block_job_next_locked(NULL); + while (job && (job->job.cancelled || + job->job.deferred_to_main_loop || + !block_job_has_bdrv(job, blk_bs(blk)))) + { + job = block_job_next_locked(job); + } + if (job) { + /* + * This drops the job lock temporarily and polls, so we need to + * restart processing the list from the start after this. + */ job_cancel_locked(&job->job, false); } - } + } while (job); dinfo->auto_del = 1; } From patchwork Thu May 4 19:53:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 13231705 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 1EF70C77B78 for ; Thu, 4 May 2023 19:53:59 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.530062.825346 (Exim 4.92) (envelope-from ) id 1puf1N-0004G8-SV; Thu, 04 May 2023 19:53:45 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 530062.825346; Thu, 04 May 2023 19:53:45 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf1N-0004Fy-Pq; Thu, 04 May 2023 19:53:45 +0000 Received: by outflank-mailman (input) for mailman id 530062; Thu, 04 May 2023 19:53:44 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf1M-0003xx-8V for xen-devel@lists.xenproject.org; Thu, 04 May 2023 19:53:44 +0000 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 5e861438-eab5-11ed-8611-37d641c3527e; Thu, 04 May 2023 21:53:42 +0200 (CEST) Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-403-PWDrmmbSNeKjFAv3qLOnZg-1; Thu, 04 May 2023 15:53:37 -0400 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.rdu2.redhat.com [10.11.54.8]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 31E0D109DCE5; Thu, 4 May 2023 19:53:36 +0000 (UTC) Received: from localhost (unknown [10.39.192.57]) by smtp.corp.redhat.com (Postfix) with ESMTP id 59BEFC15BAD; Thu, 4 May 2023 19:53:35 +0000 (UTC) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 5e861438-eab5-11ed-8611-37d641c3527e DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1683230021; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=2q86JTUb82jHsKou8iDv6+YsV2u1chyoHCqSrVQuj0g=; b=B5pQAGBnnAr0A+0xGh0wbuAruZ1+g+47gWo6+eRRnLbwl9zPOfvj1q63v6OuTe5vKic0M2 bvAcYiZhsT4glR8IbJYeqRoykfg+/DtaLLX8Zxd+7p20mKLEZMUvxn7GJjzKIwAVZC4QKu yLIcmabUUUiXUP7+hkyj2v2WoEDXtQ0= X-MC-Unique: PWDrmmbSNeKjFAv3qLOnZg-1 From: Stefan Hajnoczi To: qemu-devel@nongnu.org Cc: Ronnie Sahlberg , Aarushi Mehta , qemu-block@nongnu.org, Paul Durrant , Anthony Perard , Peter Lieven , Stefan Weil , Xie Yongji , Kevin Wolf , Paolo Bonzini , "Michael S. Tsirkin" , Leonardo Bras , Peter Xu , Hanna Reitz , Stefano Stabellini , Richard Henderson , David Woodhouse , Coiby Xu , Eduardo Habkost , Stefano Garzarella , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , Stefan Hajnoczi , Julia Suvorova , xen-devel@lists.xenproject.org, eesposit@redhat.com, Juan Quintela , "Richard W.M. Jones" , Fam Zheng , Marcel Apfelbaum Subject: [PATCH v5 02/21] block-backend: split blk_do_set_aio_context() Date: Thu, 4 May 2023 15:53:08 -0400 Message-Id: <20230504195327.695107-3-stefanha@redhat.com> In-Reply-To: <20230504195327.695107-1-stefanha@redhat.com> References: <20230504195327.695107-1-stefanha@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.8 blk_set_aio_context() is not fully transactional because blk_do_set_aio_context() updates blk->ctx outside the transaction. Most of the time this goes unnoticed but a BlockDevOps.drained_end() callback that invokes blk_get_aio_context() fails assert(ctx == blk->ctx). This happens because blk->ctx is only assigned after BlockDevOps.drained_end() is called and we're in an intermediate state where BlockDrvierState nodes already have the new context and the BlockBackend still has the old context. Making blk_set_aio_context() fully transactional solves this assertion failure because the BlockBackend's context is updated as part of the transaction (before BlockDevOps.drained_end() is called). Split blk_do_set_aio_context() in order to solve this assertion failure. This helper function actually serves two different purposes: 1. It drives blk_set_aio_context(). 2. It responds to BdrvChildClass->change_aio_ctx(). Get rid of the helper function. Do #1 inside blk_set_aio_context() and do #2 inside blk_root_set_aio_ctx_commit(). This simplifies the code. The only drawback of the fully transactional approach is that blk_set_aio_context() must contend with blk_root_set_aio_ctx_commit() being invoked as part of the AioContext change propagation. This can be solved by temporarily setting blk->allow_aio_context_change to true. Future patches call blk_get_aio_context() from BlockDevOps->drained_end(), so this patch will become necessary. Signed-off-by: Stefan Hajnoczi --- block/block-backend.c | 71 +++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 43 deletions(-) diff --git a/block/block-backend.c b/block/block-backend.c index fc530ded6a..68d38635bc 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -2205,52 +2205,31 @@ static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb) return blk_get_aio_context(blk_acb->blk); } -static int blk_do_set_aio_context(BlockBackend *blk, AioContext *new_context, - bool update_root_node, Error **errp) -{ - BlockDriverState *bs = blk_bs(blk); - ThrottleGroupMember *tgm = &blk->public.throttle_group_member; - int ret; - - if (bs) { - bdrv_ref(bs); - - if (update_root_node) { - /* - * update_root_node MUST be false for blk_root_set_aio_ctx_commit(), - * as we are already in the commit function of a transaction. - */ - ret = bdrv_try_change_aio_context(bs, new_context, blk->root, errp); - if (ret < 0) { - bdrv_unref(bs); - return ret; - } - } - /* - * Make blk->ctx consistent with the root node before we invoke any - * other operations like drain that might inquire blk->ctx - */ - blk->ctx = new_context; - if (tgm->throttle_state) { - bdrv_drained_begin(bs); - throttle_group_detach_aio_context(tgm); - throttle_group_attach_aio_context(tgm, new_context); - bdrv_drained_end(bs); - } - - bdrv_unref(bs); - } else { - blk->ctx = new_context; - } - - return 0; -} - int blk_set_aio_context(BlockBackend *blk, AioContext *new_context, Error **errp) { + bool old_allow_change; + BlockDriverState *bs = blk_bs(blk); + int ret; + GLOBAL_STATE_CODE(); - return blk_do_set_aio_context(blk, new_context, true, errp); + + if (!bs) { + blk->ctx = new_context; + return 0; + } + + bdrv_ref(bs); + + old_allow_change = blk->allow_aio_context_change; + blk->allow_aio_context_change = true; + + ret = bdrv_try_change_aio_context(bs, new_context, NULL, errp); + + blk->allow_aio_context_change = old_allow_change; + + bdrv_unref(bs); + return ret; } typedef struct BdrvStateBlkRootContext { @@ -2262,8 +2241,14 @@ static void blk_root_set_aio_ctx_commit(void *opaque) { BdrvStateBlkRootContext *s = opaque; BlockBackend *blk = s->blk; + AioContext *new_context = s->new_ctx; + ThrottleGroupMember *tgm = &blk->public.throttle_group_member; - blk_do_set_aio_context(blk, s->new_ctx, false, &error_abort); + blk->ctx = new_context; + if (tgm->throttle_state) { + throttle_group_detach_aio_context(tgm); + throttle_group_attach_aio_context(tgm, new_context); + } } static TransactionActionDrv set_blk_root_context = { From patchwork Thu May 4 19:53:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 13231703 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B3E31C7EE22 for ; Thu, 4 May 2023 19:53:56 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.530063.825356 (Exim 4.92) (envelope-from ) id 1puf1P-0004WO-4j; Thu, 04 May 2023 19:53:47 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 530063.825356; Thu, 04 May 2023 19:53:47 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf1P-0004WB-1s; Thu, 04 May 2023 19:53:47 +0000 Received: by outflank-mailman (input) for mailman id 530063; Thu, 04 May 2023 19:53:45 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf1N-0003xx-K1 for xen-devel@lists.xenproject.org; Thu, 04 May 2023 19:53:45 +0000 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 5f943d10-eab5-11ed-8611-37d641c3527e; Thu, 04 May 2023 21:53:44 +0200 (CEST) Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-300-_aYTw-OjPuqtsu_BDqa0FQ-1; Thu, 04 May 2023 15:53:39 -0400 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 8751C3813F32; Thu, 4 May 2023 19:53:38 +0000 (UTC) Received: from localhost (unknown [10.39.192.57]) by smtp.corp.redhat.com (Postfix) with ESMTP id E2CA11410DD7; Thu, 4 May 2023 19:53:37 +0000 (UTC) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 5f943d10-eab5-11ed-8611-37d641c3527e DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1683230023; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=XkgBmD/d+YGvrkKNM3PZYahxZ017Cf0e7HM4zKnGRyM=; b=hRN+vthTTk5GIzhy/fi6D2ClFGcQlDtxI7DX7m15PSDuLyMoaX2Pnf7iUoS/LJeFY9CFR3 UNesnjOaw7uQN8Q+A3WdAl9Y2qH9q0ybFlwPScOhC4jHKhf4p9dGNdAMVKAmoQAs0ay4CX hxqUNjxt3LmOaCFGwCE3Er4bPvr+oXM= X-MC-Unique: _aYTw-OjPuqtsu_BDqa0FQ-1 From: Stefan Hajnoczi To: qemu-devel@nongnu.org Cc: Ronnie Sahlberg , Aarushi Mehta , qemu-block@nongnu.org, Paul Durrant , Anthony Perard , Peter Lieven , Stefan Weil , Xie Yongji , Kevin Wolf , Paolo Bonzini , "Michael S. Tsirkin" , Leonardo Bras , Peter Xu , Hanna Reitz , Stefano Stabellini , Richard Henderson , David Woodhouse , Coiby Xu , Eduardo Habkost , Stefano Garzarella , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , Stefan Hajnoczi , Julia Suvorova , xen-devel@lists.xenproject.org, eesposit@redhat.com, Juan Quintela , "Richard W.M. Jones" , Fam Zheng , Marcel Apfelbaum Subject: [PATCH v5 03/21] hw/qdev: introduce qdev_is_realized() helper Date: Thu, 4 May 2023 15:53:09 -0400 Message-Id: <20230504195327.695107-4-stefanha@redhat.com> In-Reply-To: <20230504195327.695107-1-stefanha@redhat.com> References: <20230504195327.695107-1-stefanha@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.7 Add a helper function to check whether the device is realized without requiring the Big QEMU Lock. The next patch adds a second caller. The goal is to avoid spreading DeviceState field accesses throughout the code. Suggested-by: Philippe Mathieu-Daudé Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Stefan Hajnoczi --- include/hw/qdev-core.h | 17 ++++++++++++++--- hw/scsi/scsi-bus.c | 3 +-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index 7623703943..f1070d6dc7 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -1,6 +1,7 @@ #ifndef QDEV_CORE_H #define QDEV_CORE_H +#include "qemu/atomic.h" #include "qemu/queue.h" #include "qemu/bitmap.h" #include "qemu/rcu.h" @@ -168,9 +169,6 @@ typedef struct { /** * DeviceState: - * @realized: Indicates whether the device has been fully constructed. - * When accessed outside big qemu lock, must be accessed with - * qatomic_load_acquire() * @reset: ResettableState for the device; handled by Resettable interface. * * This structure should not be accessed directly. We declare it here @@ -339,6 +337,19 @@ DeviceState *qdev_new(const char *name); */ DeviceState *qdev_try_new(const char *name); +/** + * qdev_is_realized: + * @dev: The device to check. + * + * May be called outside big qemu lock. + * + * Returns: %true% if the device has been fully constructed, %false% otherwise. + */ +static inline bool qdev_is_realized(DeviceState *dev) +{ + return qatomic_load_acquire(&dev->realized); +} + /** * qdev_realize: Realize @dev. * @dev: device to realize diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c index 3c20b47ad0..8857ff41f6 100644 --- a/hw/scsi/scsi-bus.c +++ b/hw/scsi/scsi-bus.c @@ -60,8 +60,7 @@ static SCSIDevice *do_scsi_device_find(SCSIBus *bus, * the user access the device. */ - if (retval && !include_unrealized && - !qatomic_load_acquire(&retval->qdev.realized)) { + if (retval && !include_unrealized && !qdev_is_realized(&retval->qdev)) { retval = NULL; } From patchwork Thu May 4 19:53:10 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 13231707 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C9FBBC7EE22 for ; Thu, 4 May 2023 19:54:00 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.530064.825367 (Exim 4.92) (envelope-from ) id 1puf1R-0004pe-H7; Thu, 04 May 2023 19:53:49 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 530064.825367; Thu, 04 May 2023 19:53:49 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf1R-0004pT-Bc; Thu, 04 May 2023 19:53:49 +0000 Received: by outflank-mailman (input) for mailman id 530064; Thu, 04 May 2023 19:53:48 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf1P-0003iB-Vg for xen-devel@lists.xenproject.org; Thu, 04 May 2023 19:53:47 +0000 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 6143fca3-eab5-11ed-b226-6b7b168915f2; Thu, 04 May 2023 21:53:47 +0200 (CEST) Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-349-OwK9rzciNzal1nFRcpiK8A-1; Thu, 04 May 2023 15:53:42 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 947371C06EDA; Thu, 4 May 2023 19:53:41 +0000 (UTC) Received: from localhost (unknown [10.39.192.57]) by smtp.corp.redhat.com (Postfix) with ESMTP id A983B1121331; Thu, 4 May 2023 19:53:40 +0000 (UTC) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 6143fca3-eab5-11ed-b226-6b7b168915f2 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1683230025; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=efhUpWQleoubyTXms1hMRDqrtRfLyC1vJzKA96dtfK0=; b=bxzTsnMduWC8nIrXWM4GHUKtiPAkZrs3sRFV/V32G3rD3k0zfHga9gOLMBV3sJujIuMZJR u8DRLyMo1t9ILk7VZkh8MdGYfc/kG05b/w53dN1NRANRnJQDCc49jftb3sYyOTWn90yw8v KyaijIWomhMC/kV2gkChFnofYN5MxHQ= X-MC-Unique: OwK9rzciNzal1nFRcpiK8A-1 From: Stefan Hajnoczi To: qemu-devel@nongnu.org Cc: Ronnie Sahlberg , Aarushi Mehta , qemu-block@nongnu.org, Paul Durrant , Anthony Perard , Peter Lieven , Stefan Weil , Xie Yongji , Kevin Wolf , Paolo Bonzini , "Michael S. Tsirkin" , Leonardo Bras , Peter Xu , Hanna Reitz , Stefano Stabellini , Richard Henderson , David Woodhouse , Coiby Xu , Eduardo Habkost , Stefano Garzarella , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , Stefan Hajnoczi , Julia Suvorova , xen-devel@lists.xenproject.org, eesposit@redhat.com, Juan Quintela , "Richard W.M. Jones" , Fam Zheng , Marcel Apfelbaum , Daniil Tatianin Subject: [PATCH v5 04/21] virtio-scsi: avoid race between unplug and transport event Date: Thu, 4 May 2023 15:53:10 -0400 Message-Id: <20230504195327.695107-5-stefanha@redhat.com> In-Reply-To: <20230504195327.695107-1-stefanha@redhat.com> References: <20230504195327.695107-1-stefanha@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.3 Only report a transport reset event to the guest after the SCSIDevice has been unrealized by qdev_simple_device_unplug_cb(). qdev_simple_device_unplug_cb() sets the SCSIDevice's qdev.realized field to false so that scsi_device_find/get() no longer see it. scsi_target_emulate_report_luns() also needs to be updated to filter out SCSIDevices that are unrealized. Change virtio_scsi_push_event() to take event information as an argument instead of the SCSIDevice. This allows virtio_scsi_hotunplug() to emit a VIRTIO_SCSI_T_TRANSPORT_RESET event after the SCSIDevice has already been unrealized. These changes ensure that the guest driver does not see the SCSIDevice that's being unplugged if it responds very quickly to the transport reset event. Reviewed-by: Paolo Bonzini Reviewed-by: Michael S. Tsirkin Reviewed-by: Daniil Tatianin Signed-off-by: Stefan Hajnoczi --- v5: - Stash SCSIDevice id/lun values for VIRTIO_SCSI_T_TRANSPORT_RESET event before unrealizing the SCSIDevice [Kevin] --- hw/scsi/scsi-bus.c | 3 +- hw/scsi/virtio-scsi.c | 86 ++++++++++++++++++++++++++++++------------- 2 files changed, 63 insertions(+), 26 deletions(-) diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c index 8857ff41f6..64013c8a24 100644 --- a/hw/scsi/scsi-bus.c +++ b/hw/scsi/scsi-bus.c @@ -487,7 +487,8 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq *r) DeviceState *qdev = kid->child; SCSIDevice *dev = SCSI_DEVICE(qdev); - if (dev->channel == channel && dev->id == id && dev->lun != 0) { + if (dev->channel == channel && dev->id == id && dev->lun != 0 && + qdev_is_realized(&dev->qdev)) { store_lun(tmp, dev->lun); g_byte_array_append(buf, tmp, 8); len += 8; diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index 612c525d9d..ae314af3de 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -933,13 +933,27 @@ static void virtio_scsi_reset(VirtIODevice *vdev) s->events_dropped = false; } -static void virtio_scsi_push_event(VirtIOSCSI *s, SCSIDevice *dev, - uint32_t event, uint32_t reason) +typedef struct { + uint32_t event; + uint32_t reason; + union { + /* Used by messages specific to a device */ + struct { + uint32_t id; + uint32_t lun; + } address; + }; +} VirtIOSCSIEventInfo; + +static void virtio_scsi_push_event(VirtIOSCSI *s, + const VirtIOSCSIEventInfo *info) { VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s); VirtIOSCSIReq *req; VirtIOSCSIEvent *evt; VirtIODevice *vdev = VIRTIO_DEVICE(s); + uint32_t event = info->event; + uint32_t reason = info->reason; if (!(vdev->status & VIRTIO_CONFIG_S_DRIVER_OK)) { return; @@ -965,27 +979,28 @@ static void virtio_scsi_push_event(VirtIOSCSI *s, SCSIDevice *dev, memset(evt, 0, sizeof(VirtIOSCSIEvent)); evt->event = virtio_tswap32(vdev, event); evt->reason = virtio_tswap32(vdev, reason); - if (!dev) { - assert(event == VIRTIO_SCSI_T_EVENTS_MISSED); - } else { + if (event != VIRTIO_SCSI_T_EVENTS_MISSED) { evt->lun[0] = 1; - evt->lun[1] = dev->id; + evt->lun[1] = info->address.id; /* Linux wants us to keep the same encoding we use for REPORT LUNS. */ - if (dev->lun >= 256) { - evt->lun[2] = (dev->lun >> 8) | 0x40; + if (info->address.lun >= 256) { + evt->lun[2] = (info->address.lun >> 8) | 0x40; } - evt->lun[3] = dev->lun & 0xFF; + evt->lun[3] = info->address.lun & 0xFF; } trace_virtio_scsi_event(virtio_scsi_get_lun(evt->lun), event, reason); - + virtio_scsi_complete_req(req); } static void virtio_scsi_handle_event_vq(VirtIOSCSI *s, VirtQueue *vq) { if (s->events_dropped) { - virtio_scsi_push_event(s, NULL, VIRTIO_SCSI_T_NO_EVENT, 0); + VirtIOSCSIEventInfo info = { + .event = VIRTIO_SCSI_T_NO_EVENT, + }; + virtio_scsi_push_event(s, &info); } } @@ -1009,9 +1024,17 @@ static void virtio_scsi_change(SCSIBus *bus, SCSIDevice *dev, SCSISense sense) if (virtio_vdev_has_feature(vdev, VIRTIO_SCSI_F_CHANGE) && dev->type != TYPE_ROM) { + VirtIOSCSIEventInfo info = { + .event = VIRTIO_SCSI_T_PARAM_CHANGE, + .reason = sense.asc | (sense.ascq << 8), + .address = { + .id = dev->id, + .lun = dev->lun, + }, + }; + virtio_scsi_acquire(s); - virtio_scsi_push_event(s, dev, VIRTIO_SCSI_T_PARAM_CHANGE, - sense.asc | (sense.ascq << 8)); + virtio_scsi_push_event(s, &info); virtio_scsi_release(s); } } @@ -1046,10 +1069,17 @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev, } if (virtio_vdev_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) { + VirtIOSCSIEventInfo info = { + .event = VIRTIO_SCSI_T_TRANSPORT_RESET, + .reason = VIRTIO_SCSI_EVT_RESET_RESCAN, + .address = { + .id = sd->id, + .lun = sd->lun, + }, + }; + virtio_scsi_acquire(s); - virtio_scsi_push_event(s, sd, - VIRTIO_SCSI_T_TRANSPORT_RESET, - VIRTIO_SCSI_EVT_RESET_RESCAN); + virtio_scsi_push_event(s, &info); scsi_bus_set_ua(&s->bus, SENSE_CODE(REPORTED_LUNS_CHANGED)); virtio_scsi_release(s); } @@ -1062,15 +1092,14 @@ static void virtio_scsi_hotunplug(HotplugHandler *hotplug_dev, DeviceState *dev, VirtIOSCSI *s = VIRTIO_SCSI(vdev); SCSIDevice *sd = SCSI_DEVICE(dev); AioContext *ctx = s->ctx ?: qemu_get_aio_context(); - - if (virtio_vdev_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) { - virtio_scsi_acquire(s); - virtio_scsi_push_event(s, sd, - VIRTIO_SCSI_T_TRANSPORT_RESET, - VIRTIO_SCSI_EVT_RESET_REMOVED); - scsi_bus_set_ua(&s->bus, SENSE_CODE(REPORTED_LUNS_CHANGED)); - virtio_scsi_release(s); - } + VirtIOSCSIEventInfo info = { + .event = VIRTIO_SCSI_T_TRANSPORT_RESET, + .reason = VIRTIO_SCSI_EVT_RESET_REMOVED, + .address = { + .id = sd->id, + .lun = sd->lun, + }, + }; aio_disable_external(ctx); qdev_simple_device_unplug_cb(hotplug_dev, dev, errp); @@ -1082,6 +1111,13 @@ static void virtio_scsi_hotunplug(HotplugHandler *hotplug_dev, DeviceState *dev, blk_set_aio_context(sd->conf.blk, qemu_get_aio_context(), NULL); virtio_scsi_release(s); } + + if (virtio_vdev_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) { + virtio_scsi_acquire(s); + virtio_scsi_push_event(s, &info); + scsi_bus_set_ua(&s->bus, SENSE_CODE(REPORTED_LUNS_CHANGED)); + virtio_scsi_release(s); + } } static struct SCSIBusInfo virtio_scsi_scsi_info = { From patchwork Thu May 4 19:53:11 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 13231708 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 3B637C7EE21 for ; Thu, 4 May 2023 19:54:02 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.530065.825376 (Exim 4.92) (envelope-from ) id 1puf1S-00058M-Sn; Thu, 04 May 2023 19:53:50 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 530065.825376; Thu, 04 May 2023 19:53:50 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf1S-000587-PE; Thu, 04 May 2023 19:53:50 +0000 Received: by outflank-mailman (input) for mailman id 530065; Thu, 04 May 2023 19:53:50 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf1S-0003iB-6q for xen-devel@lists.xenproject.org; Thu, 04 May 2023 19:53:50 +0000 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 62cc8225-eab5-11ed-b226-6b7b168915f2; Thu, 04 May 2023 21:53:49 +0200 (CEST) Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-270-GII9Yb4pMlSDS5YQk3vVsA-1; Thu, 04 May 2023 15:53:45 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 145C8886064; Thu, 4 May 2023 19:53:44 +0000 (UTC) Received: from localhost (unknown [10.39.192.57]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6F9C31121331; Thu, 4 May 2023 19:53:43 +0000 (UTC) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 62cc8225-eab5-11ed-b226-6b7b168915f2 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1683230028; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=4aDv9+T5dXOUzGaYXYbFqi/phBTNlR0gw0d5Reej/CE=; b=RtWK7gEll8TwVEL8NE+0RnxDxnpO/js06J9+6G+jPK+WKu4bRKOg1RyDV31BTJPu6xh7Ub XST7dTb33KmjjnrNStDzpJuM6jcdxTpgA/SSUaYErf85suAJoB09DR/K9hIOIdF+MAkyy/ QeA4mB/e1Lz09zUD84XJq2L8LI+SCt8= X-MC-Unique: GII9Yb4pMlSDS5YQk3vVsA-1 From: Stefan Hajnoczi To: qemu-devel@nongnu.org Cc: Ronnie Sahlberg , Aarushi Mehta , qemu-block@nongnu.org, Paul Durrant , Anthony Perard , Peter Lieven , Stefan Weil , Xie Yongji , Kevin Wolf , Paolo Bonzini , "Michael S. Tsirkin" , Leonardo Bras , Peter Xu , Hanna Reitz , Stefano Stabellini , Richard Henderson , David Woodhouse , Coiby Xu , Eduardo Habkost , Stefano Garzarella , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , Stefan Hajnoczi , Julia Suvorova , xen-devel@lists.xenproject.org, eesposit@redhat.com, Juan Quintela , "Richard W.M. Jones" , Fam Zheng , Marcel Apfelbaum , Zhengui Li , Daniil Tatianin Subject: [PATCH v5 05/21] virtio-scsi: stop using aio_disable_external() during unplug Date: Thu, 4 May 2023 15:53:11 -0400 Message-Id: <20230504195327.695107-6-stefanha@redhat.com> In-Reply-To: <20230504195327.695107-1-stefanha@redhat.com> References: <20230504195327.695107-1-stefanha@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.3 This patch is part of an effort to remove the aio_disable_external() API because it does not fit in a multi-queue block layer world where many AioContexts may be submitting requests to the same disk. The SCSI emulation code is already in good shape to stop using aio_disable_external(). It was only used by commit 9c5aad84da1c ("virtio-scsi: fixed virtio_scsi_ctx_check failed when detaching scsi disk") to ensure that virtio_scsi_hotunplug() works while the guest driver is submitting I/O. Ensure virtio_scsi_hotunplug() is safe as follows: 1. qdev_simple_device_unplug_cb() -> qdev_unrealize() -> device_set_realized() calls qatomic_set(&dev->realized, false) so that future scsi_device_get() calls return NULL because they exclude SCSIDevices with realized=false. That means virtio-scsi will reject new I/O requests to this SCSIDevice with VIRTIO_SCSI_S_BAD_TARGET even while virtio_scsi_hotunplug() is still executing. We are protected against new requests! 2. scsi_device_unrealize() already contains a call to scsi_device_purge_requests() so that in-flight requests are cancelled synchronously. This ensures that no in-flight requests remain once qdev_simple_device_unplug_cb() returns. Thanks to these two conditions we don't need aio_disable_external() anymore. Cc: Zhengui Li Reviewed-by: Paolo Bonzini Reviewed-by: Daniil Tatianin Signed-off-by: Stefan Hajnoczi --- hw/scsi/virtio-scsi.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index ae314af3de..c1a7ea9ae2 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -1091,7 +1091,6 @@ static void virtio_scsi_hotunplug(HotplugHandler *hotplug_dev, DeviceState *dev, VirtIODevice *vdev = VIRTIO_DEVICE(hotplug_dev); VirtIOSCSI *s = VIRTIO_SCSI(vdev); SCSIDevice *sd = SCSI_DEVICE(dev); - AioContext *ctx = s->ctx ?: qemu_get_aio_context(); VirtIOSCSIEventInfo info = { .event = VIRTIO_SCSI_T_TRANSPORT_RESET, .reason = VIRTIO_SCSI_EVT_RESET_REMOVED, @@ -1101,9 +1100,7 @@ static void virtio_scsi_hotunplug(HotplugHandler *hotplug_dev, DeviceState *dev, }, }; - aio_disable_external(ctx); qdev_simple_device_unplug_cb(hotplug_dev, dev, errp); - aio_enable_external(ctx); if (s->ctx) { virtio_scsi_acquire(s); From patchwork Thu May 4 19:53:12 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 13231710 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 7B835C7EE2C for ; Thu, 4 May 2023 19:54:06 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.530066.825385 (Exim 4.92) (envelope-from ) id 1puf1U-0005Pi-7H; Thu, 04 May 2023 19:53:52 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 530066.825385; Thu, 04 May 2023 19:53:52 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf1U-0005P9-4L; Thu, 04 May 2023 19:53:52 +0000 Received: by outflank-mailman (input) for mailman id 530066; Thu, 04 May 2023 19:53:51 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf1T-0003iB-C6 for xen-devel@lists.xenproject.org; Thu, 04 May 2023 19:53:51 +0000 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 6378c682-eab5-11ed-b226-6b7b168915f2; Thu, 04 May 2023 21:53:50 +0200 (CEST) Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-471-Q3sOoSu5NLOST1Dr08hq8A-1; Thu, 04 May 2023 15:53:48 -0400 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id D133A811E7B; Thu, 4 May 2023 19:53:46 +0000 (UTC) Received: from localhost (unknown [10.39.192.57]) by smtp.corp.redhat.com (Postfix) with ESMTP id 35F9F1410F29; Thu, 4 May 2023 19:53:45 +0000 (UTC) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 6378c682-eab5-11ed-b226-6b7b168915f2 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1683230029; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Uh9JsAzQBVO7FYeYzOSkBp65HQ8Exa/aGS/jTv3In5w=; b=EzZQBmmhNU4ngSGJiFO3DnxrSckJJBnghhkyNeVJXLS0C5BOvjHPSqdaNsbAB27GKPdln4 TZPPF56oof8Ztitpzo9qCrWwFS3b2PO6Dbr4/8nfab7sPM5rL6NQnlBwe8oSYm9u2an1Zc lVLQ13sCnnKTIaGjt41I5Qd5tcg/LXo= X-MC-Unique: Q3sOoSu5NLOST1Dr08hq8A-1 From: Stefan Hajnoczi To: qemu-devel@nongnu.org Cc: Ronnie Sahlberg , Aarushi Mehta , qemu-block@nongnu.org, Paul Durrant , Anthony Perard , Peter Lieven , Stefan Weil , Xie Yongji , Kevin Wolf , Paolo Bonzini , "Michael S. Tsirkin" , Leonardo Bras , Peter Xu , Hanna Reitz , Stefano Stabellini , Richard Henderson , David Woodhouse , Coiby Xu , Eduardo Habkost , Stefano Garzarella , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , Stefan Hajnoczi , Julia Suvorova , xen-devel@lists.xenproject.org, eesposit@redhat.com, Juan Quintela , "Richard W.M. Jones" , Fam Zheng , Marcel Apfelbaum Subject: [PATCH v5 06/21] util/vhost-user-server: rename refcount to in_flight counter Date: Thu, 4 May 2023 15:53:12 -0400 Message-Id: <20230504195327.695107-7-stefanha@redhat.com> In-Reply-To: <20230504195327.695107-1-stefanha@redhat.com> References: <20230504195327.695107-1-stefanha@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.7 The VuServer object has a refcount field and ref/unref APIs. The name is confusing because it's actually an in-flight request counter instead of a refcount. Normally a refcount destroys the object upon reaching zero. The VuServer counter is used to wake up the vhost-user coroutine when there are no more requests. Avoid confusing by renaming refcount and ref/unref to in_flight and inc/dec. Reviewed-by: Paolo Bonzini Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Stefan Hajnoczi --- include/qemu/vhost-user-server.h | 6 +++--- block/export/vhost-user-blk-server.c | 11 +++++++---- util/vhost-user-server.c | 14 +++++++------- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/include/qemu/vhost-user-server.h b/include/qemu/vhost-user-server.h index 25c72433ca..bc0ac9ddb6 100644 --- a/include/qemu/vhost-user-server.h +++ b/include/qemu/vhost-user-server.h @@ -41,7 +41,7 @@ typedef struct { const VuDevIface *vu_iface; /* Protected by ctx lock */ - unsigned int refcount; + unsigned int in_flight; bool wait_idle; VuDev vu_dev; QIOChannel *ioc; /* The I/O channel with the client */ @@ -60,8 +60,8 @@ bool vhost_user_server_start(VuServer *server, void vhost_user_server_stop(VuServer *server); -void vhost_user_server_ref(VuServer *server); -void vhost_user_server_unref(VuServer *server); +void vhost_user_server_inc_in_flight(VuServer *server); +void vhost_user_server_dec_in_flight(VuServer *server); void vhost_user_server_attach_aio_context(VuServer *server, AioContext *ctx); void vhost_user_server_detach_aio_context(VuServer *server); diff --git a/block/export/vhost-user-blk-server.c b/block/export/vhost-user-blk-server.c index e56b92f2e2..841acb36e3 100644 --- a/block/export/vhost-user-blk-server.c +++ b/block/export/vhost-user-blk-server.c @@ -50,7 +50,10 @@ static void vu_blk_req_complete(VuBlkReq *req, size_t in_len) free(req); } -/* Called with server refcount increased, must decrease before returning */ +/* + * Called with server in_flight counter increased, must decrease before + * returning. + */ static void coroutine_fn vu_blk_virtio_process_req(void *opaque) { VuBlkReq *req = opaque; @@ -68,12 +71,12 @@ static void coroutine_fn vu_blk_virtio_process_req(void *opaque) in_num, out_num); if (in_len < 0) { free(req); - vhost_user_server_unref(server); + vhost_user_server_dec_in_flight(server); return; } vu_blk_req_complete(req, in_len); - vhost_user_server_unref(server); + vhost_user_server_dec_in_flight(server); } static void vu_blk_process_vq(VuDev *vu_dev, int idx) @@ -95,7 +98,7 @@ static void vu_blk_process_vq(VuDev *vu_dev, int idx) Coroutine *co = qemu_coroutine_create(vu_blk_virtio_process_req, req); - vhost_user_server_ref(server); + vhost_user_server_inc_in_flight(server); qemu_coroutine_enter(co); } } diff --git a/util/vhost-user-server.c b/util/vhost-user-server.c index 5b6216069c..1622f8cfb3 100644 --- a/util/vhost-user-server.c +++ b/util/vhost-user-server.c @@ -75,16 +75,16 @@ static void panic_cb(VuDev *vu_dev, const char *buf) error_report("vu_panic: %s", buf); } -void vhost_user_server_ref(VuServer *server) +void vhost_user_server_inc_in_flight(VuServer *server) { assert(!server->wait_idle); - server->refcount++; + server->in_flight++; } -void vhost_user_server_unref(VuServer *server) +void vhost_user_server_dec_in_flight(VuServer *server) { - server->refcount--; - if (server->wait_idle && !server->refcount) { + server->in_flight--; + if (server->wait_idle && !server->in_flight) { aio_co_wake(server->co_trip); } } @@ -192,13 +192,13 @@ static coroutine_fn void vu_client_trip(void *opaque) /* Keep running */ } - if (server->refcount) { + if (server->in_flight) { /* Wait for requests to complete before we can unmap the memory */ server->wait_idle = true; qemu_coroutine_yield(); server->wait_idle = false; } - assert(server->refcount == 0); + assert(server->in_flight == 0); vu_deinit(vu_dev); From patchwork Thu May 4 19:53:13 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 13231709 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 0C4EEC7EE25 for ; Thu, 4 May 2023 19:54:06 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.530068.825395 (Exim 4.92) (envelope-from ) id 1puf1Z-0005vK-Gc; Thu, 04 May 2023 19:53:57 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 530068.825395; Thu, 04 May 2023 19:53:57 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf1Z-0005v2-DY; Thu, 04 May 2023 19:53:57 +0000 Received: by outflank-mailman (input) for mailman id 530068; Thu, 04 May 2023 19:53:56 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf1Y-0003xx-Bh for xen-devel@lists.xenproject.org; Thu, 04 May 2023 19:53:56 +0000 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 65cbde11-eab5-11ed-8611-37d641c3527e; Thu, 04 May 2023 21:53:54 +0200 (CEST) Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-569-tNtDfOKSMVq3AQX3nRbV7g-1; Thu, 04 May 2023 15:53:50 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 36B9A101A550; Thu, 4 May 2023 19:53:49 +0000 (UTC) Received: from localhost (unknown [10.39.192.57]) by smtp.corp.redhat.com (Postfix) with ESMTP id 931081121339; Thu, 4 May 2023 19:53:48 +0000 (UTC) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 65cbde11-eab5-11ed-8611-37d641c3527e DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1683230033; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=uqVEulc+YKH8du/OTtIOC0bNRzxnvgw0ufD9riF8H3c=; b=ZXxeazJeqhC4n051eeKdQiY8H06cimgZClzH2ZDzMvw4+Jirga4fZkLq2fKXl3IqTpDd3y F7Zfq75R/q9dufnBuyZDMM++8mpT5R6oOl4MJDfAZ4+tF227ZoXve/MGRIhIzwXI1BuYxu egnWeY26hjGFsmL2XPrSMDcLZIdGZ5s= X-MC-Unique: tNtDfOKSMVq3AQX3nRbV7g-1 From: Stefan Hajnoczi To: qemu-devel@nongnu.org Cc: Ronnie Sahlberg , Aarushi Mehta , qemu-block@nongnu.org, Paul Durrant , Anthony Perard , Peter Lieven , Stefan Weil , Xie Yongji , Kevin Wolf , Paolo Bonzini , "Michael S. Tsirkin" , Leonardo Bras , Peter Xu , Hanna Reitz , Stefano Stabellini , Richard Henderson , David Woodhouse , Coiby Xu , Eduardo Habkost , Stefano Garzarella , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , Stefan Hajnoczi , Julia Suvorova , xen-devel@lists.xenproject.org, eesposit@redhat.com, Juan Quintela , "Richard W.M. Jones" , Fam Zheng , Marcel Apfelbaum Subject: [PATCH v5 07/21] block/export: wait for vhost-user-blk requests when draining Date: Thu, 4 May 2023 15:53:13 -0400 Message-Id: <20230504195327.695107-8-stefanha@redhat.com> In-Reply-To: <20230504195327.695107-1-stefanha@redhat.com> References: <20230504195327.695107-1-stefanha@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.3 Each vhost-user-blk request runs in a coroutine. When the BlockBackend enters a drained section we need to enter a quiescent state. Currently any in-flight requests race with bdrv_drained_begin() because it is unaware of vhost-user-blk requests. When blk_co_preadv/pwritev()/etc returns it wakes the bdrv_drained_begin() thread but vhost-user-blk request processing has not yet finished. The request coroutine continues executing while the main loop thread thinks it is in a drained section. One example where this is unsafe is for blk_set_aio_context() where bdrv_drained_begin() is called before .aio_context_detached() and .aio_context_attach(). If request coroutines are still running after bdrv_drained_begin(), then the AioContext could change underneath them and they race with new requests processed in the new AioContext. This could lead to virtqueue corruption, for example. (This example is theoretical, I came across this while reading the code and have not tried to reproduce it.) It's easy to make bdrv_drained_begin() wait for in-flight requests: add a .drained_poll() callback that checks the VuServer's in-flight counter. VuServer just needs an API that returns true when there are requests in flight. The in-flight counter needs to be atomic. Signed-off-by: Stefan Hajnoczi --- v5: - Use atomic accesses for in_flight counter in vhost-user-server.c [Kevin] --- include/qemu/vhost-user-server.h | 4 +++- block/export/vhost-user-blk-server.c | 13 +++++++++++++ util/vhost-user-server.c | 18 ++++++++++++------ 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/include/qemu/vhost-user-server.h b/include/qemu/vhost-user-server.h index bc0ac9ddb6..b1c1cda886 100644 --- a/include/qemu/vhost-user-server.h +++ b/include/qemu/vhost-user-server.h @@ -40,8 +40,9 @@ typedef struct { int max_queues; const VuDevIface *vu_iface; + unsigned int in_flight; /* atomic */ + /* Protected by ctx lock */ - unsigned int in_flight; bool wait_idle; VuDev vu_dev; QIOChannel *ioc; /* The I/O channel with the client */ @@ -62,6 +63,7 @@ void vhost_user_server_stop(VuServer *server); void vhost_user_server_inc_in_flight(VuServer *server); void vhost_user_server_dec_in_flight(VuServer *server); +bool vhost_user_server_has_in_flight(VuServer *server); void vhost_user_server_attach_aio_context(VuServer *server, AioContext *ctx); void vhost_user_server_detach_aio_context(VuServer *server); diff --git a/block/export/vhost-user-blk-server.c b/block/export/vhost-user-blk-server.c index 841acb36e3..f51a36a14f 100644 --- a/block/export/vhost-user-blk-server.c +++ b/block/export/vhost-user-blk-server.c @@ -272,7 +272,20 @@ static void vu_blk_exp_resize(void *opaque) vu_config_change_msg(&vexp->vu_server.vu_dev); } +/* + * Ensures that bdrv_drained_begin() waits until in-flight requests complete. + * + * Called with vexp->export.ctx acquired. + */ +static bool vu_blk_drained_poll(void *opaque) +{ + VuBlkExport *vexp = opaque; + + return vhost_user_server_has_in_flight(&vexp->vu_server); +} + static const BlockDevOps vu_blk_dev_ops = { + .drained_poll = vu_blk_drained_poll, .resize_cb = vu_blk_exp_resize, }; diff --git a/util/vhost-user-server.c b/util/vhost-user-server.c index 1622f8cfb3..68c3bf162f 100644 --- a/util/vhost-user-server.c +++ b/util/vhost-user-server.c @@ -78,17 +78,23 @@ static void panic_cb(VuDev *vu_dev, const char *buf) void vhost_user_server_inc_in_flight(VuServer *server) { assert(!server->wait_idle); - server->in_flight++; + qatomic_inc(&server->in_flight); } void vhost_user_server_dec_in_flight(VuServer *server) { - server->in_flight--; - if (server->wait_idle && !server->in_flight) { - aio_co_wake(server->co_trip); + if (qatomic_fetch_dec(&server->in_flight) == 1) { + if (server->wait_idle) { + aio_co_wake(server->co_trip); + } } } +bool vhost_user_server_has_in_flight(VuServer *server) +{ + return qatomic_load_acquire(&server->in_flight) > 0; +} + static bool coroutine_fn vu_message_read(VuDev *vu_dev, int conn_fd, VhostUserMsg *vmsg) { @@ -192,13 +198,13 @@ static coroutine_fn void vu_client_trip(void *opaque) /* Keep running */ } - if (server->in_flight) { + if (vhost_user_server_has_in_flight(server)) { /* Wait for requests to complete before we can unmap the memory */ server->wait_idle = true; qemu_coroutine_yield(); server->wait_idle = false; } - assert(server->in_flight == 0); + assert(!vhost_user_server_has_in_flight(server)); vu_deinit(vu_dev); From patchwork Thu May 4 19:53:14 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 13231712 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 98F80C7EE22 for ; Thu, 4 May 2023 19:54:11 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.530072.825412 (Exim 4.92) (envelope-from ) id 1puf1d-0006UN-HU; Thu, 04 May 2023 19:54:01 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 530072.825412; Thu, 04 May 2023 19:54:01 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf1d-0006Ta-5U; Thu, 04 May 2023 19:54:01 +0000 Received: by outflank-mailman (input) for mailman id 530072; Thu, 04 May 2023 19:54:00 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf1c-0003xx-Ev for xen-devel@lists.xenproject.org; Thu, 04 May 2023 19:54:00 +0000 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 686588fd-eab5-11ed-8611-37d641c3527e; Thu, 04 May 2023 21:53:58 +0200 (CEST) Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-610-ZoYT6p5PP2qo_FQgwkpEwA-1; Thu, 04 May 2023 15:53:52 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.rdu2.redhat.com [10.11.54.2]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 822BD185A78B; Thu, 4 May 2023 19:53:51 +0000 (UTC) Received: from localhost (unknown [10.39.192.57]) by smtp.corp.redhat.com (Postfix) with ESMTP id E35D84020960; Thu, 4 May 2023 19:53:50 +0000 (UTC) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 686588fd-eab5-11ed-8611-37d641c3527e DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1683230037; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=9wCNZYyVdjWaoTznBC2Ylnqhccg5NnPq2nFPN+RMgeA=; b=gn2qlPFGkA6wq44f0pNjMqZc6MsNtnVMUSDckB9UI1xTHwv6IDfMKvekI7Ys4wOojFka3y st6usqnqwFeV5Fh4N8wuAv6YRxmJUyRCjknlVJjLFgATm8oGDryLDytx4GxsDMp46N65WT orxFiyYfYSt3UD3Lng0+W9bipT7njbM= X-MC-Unique: ZoYT6p5PP2qo_FQgwkpEwA-1 From: Stefan Hajnoczi To: qemu-devel@nongnu.org Cc: Ronnie Sahlberg , Aarushi Mehta , qemu-block@nongnu.org, Paul Durrant , Anthony Perard , Peter Lieven , Stefan Weil , Xie Yongji , Kevin Wolf , Paolo Bonzini , "Michael S. Tsirkin" , Leonardo Bras , Peter Xu , Hanna Reitz , Stefano Stabellini , Richard Henderson , David Woodhouse , Coiby Xu , Eduardo Habkost , Stefano Garzarella , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , Stefan Hajnoczi , Julia Suvorova , xen-devel@lists.xenproject.org, eesposit@redhat.com, Juan Quintela , "Richard W.M. Jones" , Fam Zheng , Marcel Apfelbaum Subject: [PATCH v5 08/21] block/export: stop using is_external in vhost-user-blk server Date: Thu, 4 May 2023 15:53:14 -0400 Message-Id: <20230504195327.695107-9-stefanha@redhat.com> In-Reply-To: <20230504195327.695107-1-stefanha@redhat.com> References: <20230504195327.695107-1-stefanha@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.2 vhost-user activity must be suspended during bdrv_drained_begin/end(). This prevents new requests from interfering with whatever is happening in the drained section. Previously this was done using aio_set_fd_handler()'s is_external argument. In a multi-queue block layer world the aio_disable_external() API cannot be used since multiple AioContext may be processing I/O, not just one. Switch to BlockDevOps->drained_begin/end() callbacks. Signed-off-by: Stefan Hajnoczi --- block/export/vhost-user-blk-server.c | 28 ++++++++++++++++++++++++++-- util/vhost-user-server.c | 10 +++++----- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/block/export/vhost-user-blk-server.c b/block/export/vhost-user-blk-server.c index f51a36a14f..81b59761e3 100644 --- a/block/export/vhost-user-blk-server.c +++ b/block/export/vhost-user-blk-server.c @@ -212,15 +212,21 @@ static void blk_aio_attached(AioContext *ctx, void *opaque) { VuBlkExport *vexp = opaque; + /* + * The actual attach will happen in vu_blk_drained_end() and we just + * restore ctx here. + */ vexp->export.ctx = ctx; - vhost_user_server_attach_aio_context(&vexp->vu_server, ctx); } static void blk_aio_detach(void *opaque) { VuBlkExport *vexp = opaque; - vhost_user_server_detach_aio_context(&vexp->vu_server); + /* + * The actual detach already happened in vu_blk_drained_begin() but from + * this point on we must not access ctx anymore. + */ vexp->export.ctx = NULL; } @@ -272,6 +278,22 @@ static void vu_blk_exp_resize(void *opaque) vu_config_change_msg(&vexp->vu_server.vu_dev); } +/* Called with vexp->export.ctx acquired */ +static void vu_blk_drained_begin(void *opaque) +{ + VuBlkExport *vexp = opaque; + + vhost_user_server_detach_aio_context(&vexp->vu_server); +} + +/* Called with vexp->export.blk AioContext acquired */ +static void vu_blk_drained_end(void *opaque) +{ + VuBlkExport *vexp = opaque; + + vhost_user_server_attach_aio_context(&vexp->vu_server, vexp->export.ctx); +} + /* * Ensures that bdrv_drained_begin() waits until in-flight requests complete. * @@ -285,6 +307,8 @@ static bool vu_blk_drained_poll(void *opaque) } static const BlockDevOps vu_blk_dev_ops = { + .drained_begin = vu_blk_drained_begin, + .drained_end = vu_blk_drained_end, .drained_poll = vu_blk_drained_poll, .resize_cb = vu_blk_exp_resize, }; diff --git a/util/vhost-user-server.c b/util/vhost-user-server.c index 68c3bf162f..a12b2d1bba 100644 --- a/util/vhost-user-server.c +++ b/util/vhost-user-server.c @@ -278,7 +278,7 @@ set_watch(VuDev *vu_dev, int fd, int vu_evt, vu_fd_watch->fd = fd; vu_fd_watch->cb = cb; qemu_socket_set_nonblock(fd); - aio_set_fd_handler(server->ioc->ctx, fd, true, kick_handler, + aio_set_fd_handler(server->ioc->ctx, fd, false, kick_handler, NULL, NULL, NULL, vu_fd_watch); vu_fd_watch->vu_dev = vu_dev; vu_fd_watch->pvt = pvt; @@ -299,7 +299,7 @@ static void remove_watch(VuDev *vu_dev, int fd) if (!vu_fd_watch) { return; } - aio_set_fd_handler(server->ioc->ctx, fd, true, + aio_set_fd_handler(server->ioc->ctx, fd, false, NULL, NULL, NULL, NULL, NULL); QTAILQ_REMOVE(&server->vu_fd_watches, vu_fd_watch, next); @@ -362,7 +362,7 @@ void vhost_user_server_stop(VuServer *server) VuFdWatch *vu_fd_watch; QTAILQ_FOREACH(vu_fd_watch, &server->vu_fd_watches, next) { - aio_set_fd_handler(server->ctx, vu_fd_watch->fd, true, + aio_set_fd_handler(server->ctx, vu_fd_watch->fd, false, NULL, NULL, NULL, NULL, vu_fd_watch); } @@ -403,7 +403,7 @@ void vhost_user_server_attach_aio_context(VuServer *server, AioContext *ctx) qio_channel_attach_aio_context(server->ioc, ctx); QTAILQ_FOREACH(vu_fd_watch, &server->vu_fd_watches, next) { - aio_set_fd_handler(ctx, vu_fd_watch->fd, true, kick_handler, NULL, + aio_set_fd_handler(ctx, vu_fd_watch->fd, false, kick_handler, NULL, NULL, NULL, vu_fd_watch); } @@ -417,7 +417,7 @@ void vhost_user_server_detach_aio_context(VuServer *server) VuFdWatch *vu_fd_watch; QTAILQ_FOREACH(vu_fd_watch, &server->vu_fd_watches, next) { - aio_set_fd_handler(server->ctx, vu_fd_watch->fd, true, + aio_set_fd_handler(server->ctx, vu_fd_watch->fd, false, NULL, NULL, NULL, NULL, vu_fd_watch); } From patchwork Thu May 4 19:53:15 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 13231711 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 9F6C1C7EE29 for ; Thu, 4 May 2023 19:54:10 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.530071.825405 (Exim 4.92) (envelope-from ) id 1puf1c-0006Qe-Ul; Thu, 04 May 2023 19:54:00 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 530071.825405; Thu, 04 May 2023 19:54:00 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf1c-0006QR-Pu; Thu, 04 May 2023 19:54:00 +0000 Received: by outflank-mailman (input) for mailman id 530071; Thu, 04 May 2023 19:53:59 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf1b-0003iB-C9 for xen-devel@lists.xenproject.org; Thu, 04 May 2023 19:53:59 +0000 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 68646d91-eab5-11ed-b226-6b7b168915f2; Thu, 04 May 2023 21:53:58 +0200 (CEST) Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-544-TbrqFLPtO9Gbo9gH3K6ilQ-1; Thu, 04 May 2023 15:53:55 -0400 Received: from smtp.corp.redhat.com (int-mx09.intmail.prod.int.rdu2.redhat.com [10.11.54.9]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 1EC7E28004A1; Thu, 4 May 2023 19:53:54 +0000 (UTC) Received: from localhost (unknown [10.39.192.57]) by smtp.corp.redhat.com (Postfix) with ESMTP id 45ECB492C13; Thu, 4 May 2023 19:53:52 +0000 (UTC) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 68646d91-eab5-11ed-b226-6b7b168915f2 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1683230037; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=1fEremRCY5+rqiCKEtAZVyetsPRT+IQwYtOmlYy+nxY=; b=Zdw+c2FzDtVKCppbVvwL+91GFXW8cfH6HTo4hGJJO2IhBtXiMf9BWYn9lBKmCRzhVJA39D m/71AWM8S5TBpsXyc7sbTY7AIpMv/McNADPmaMvm/hSQVujBaYFufkyQJEgvwyI9n0xVtr DoNMVJZIgy/3ZPnUVIpWu7yEwtaJkmQ= X-MC-Unique: TbrqFLPtO9Gbo9gH3K6ilQ-1 From: Stefan Hajnoczi To: qemu-devel@nongnu.org Cc: Ronnie Sahlberg , Aarushi Mehta , qemu-block@nongnu.org, Paul Durrant , Anthony Perard , Peter Lieven , Stefan Weil , Xie Yongji , Kevin Wolf , Paolo Bonzini , "Michael S. Tsirkin" , Leonardo Bras , Peter Xu , Hanna Reitz , Stefano Stabellini , Richard Henderson , David Woodhouse , Coiby Xu , Eduardo Habkost , Stefano Garzarella , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , Stefan Hajnoczi , Julia Suvorova , xen-devel@lists.xenproject.org, eesposit@redhat.com, Juan Quintela , "Richard W.M. Jones" , Fam Zheng , Marcel Apfelbaum , David Woodhouse Subject: [PATCH v5 09/21] hw/xen: do not use aio_set_fd_handler(is_external=true) in xen_xenstore Date: Thu, 4 May 2023 15:53:15 -0400 Message-Id: <20230504195327.695107-10-stefanha@redhat.com> In-Reply-To: <20230504195327.695107-1-stefanha@redhat.com> References: <20230504195327.695107-1-stefanha@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.9 There is no need to suspend activity between aio_disable_external() and aio_enable_external(), which is mainly used for the block layer's drain operation. This is part of ongoing work to remove the aio_disable_external() API. Reviewed-by: David Woodhouse Reviewed-by: Paul Durrant Signed-off-by: Stefan Hajnoczi --- hw/i386/kvm/xen_xenstore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/i386/kvm/xen_xenstore.c b/hw/i386/kvm/xen_xenstore.c index 900679af8a..6e81bc8791 100644 --- a/hw/i386/kvm/xen_xenstore.c +++ b/hw/i386/kvm/xen_xenstore.c @@ -133,7 +133,7 @@ static void xen_xenstore_realize(DeviceState *dev, Error **errp) error_setg(errp, "Xenstore evtchn port init failed"); return; } - aio_set_fd_handler(qemu_get_aio_context(), xen_be_evtchn_fd(s->eh), true, + aio_set_fd_handler(qemu_get_aio_context(), xen_be_evtchn_fd(s->eh), false, xen_xenstore_event, NULL, NULL, NULL, s); s->impl = xs_impl_create(xen_domid); From patchwork Thu May 4 19:53:16 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 13231713 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 6B5EAC7EE21 for ; Thu, 4 May 2023 19:54:20 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.530078.825426 (Exim 4.92) (envelope-from ) id 1puf1l-0007Rz-QR; Thu, 04 May 2023 19:54:09 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 530078.825426; Thu, 04 May 2023 19:54:09 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf1l-0007Ro-NM; Thu, 04 May 2023 19:54:09 +0000 Received: by outflank-mailman (input) for mailman id 530078; Thu, 04 May 2023 19:54:07 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf1j-0003xx-U2 for xen-devel@lists.xenproject.org; Thu, 04 May 2023 19:54:07 +0000 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 6c9f016d-eab5-11ed-8611-37d641c3527e; Thu, 04 May 2023 21:54:05 +0200 (CEST) Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-578-Mxyocj34PQiIzWFYqCzlBA-1; Thu, 04 May 2023 15:53:57 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.rdu2.redhat.com [10.11.54.2]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 7FA16109DCE6; Thu, 4 May 2023 19:53:56 +0000 (UTC) Received: from localhost (unknown [10.39.192.57]) by smtp.corp.redhat.com (Postfix) with ESMTP id E89F34020960; Thu, 4 May 2023 19:53:55 +0000 (UTC) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 6c9f016d-eab5-11ed-8611-37d641c3527e DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1683230044; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=SzNG6z7bzqGXyIR92raSnZpugRplPdo5zETBQKXUCHA=; b=HuZdHGRXreTp69OP9K9ShnZSxMlFkSYNxaNfgU40Dh5apVw4fFYKQ1MjBbDdhKwyVqsayC 8t0WiBpvdljL/PWCpz4FGcFUfIaa/cbl06Nvl4e115j4dYbbrYE+8MGgHodhOuWSZ+8okM 1qxI8WvlLw2QBnF3UDW5fzoPjYyUhMs= X-MC-Unique: Mxyocj34PQiIzWFYqCzlBA-1 From: Stefan Hajnoczi To: qemu-devel@nongnu.org Cc: Ronnie Sahlberg , Aarushi Mehta , qemu-block@nongnu.org, Paul Durrant , Anthony Perard , Peter Lieven , Stefan Weil , Xie Yongji , Kevin Wolf , Paolo Bonzini , "Michael S. Tsirkin" , Leonardo Bras , Peter Xu , Hanna Reitz , Stefano Stabellini , Richard Henderson , David Woodhouse , Coiby Xu , Eduardo Habkost , Stefano Garzarella , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , Stefan Hajnoczi , Julia Suvorova , xen-devel@lists.xenproject.org, eesposit@redhat.com, Juan Quintela , "Richard W.M. Jones" , Fam Zheng , Marcel Apfelbaum Subject: [PATCH v5 10/21] block: add blk_in_drain() API Date: Thu, 4 May 2023 15:53:16 -0400 Message-Id: <20230504195327.695107-11-stefanha@redhat.com> In-Reply-To: <20230504195327.695107-1-stefanha@redhat.com> References: <20230504195327.695107-1-stefanha@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.2 The BlockBackend quiesce_counter is greater than zero during drained sections. Add an API to check whether the BlockBackend is in a drained section. The next patch will use this API. Signed-off-by: Stefan Hajnoczi --- include/sysemu/block-backend-global-state.h | 1 + block/block-backend.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/include/sysemu/block-backend-global-state.h b/include/sysemu/block-backend-global-state.h index 2b6d27db7c..ac7cbd6b5e 100644 --- a/include/sysemu/block-backend-global-state.h +++ b/include/sysemu/block-backend-global-state.h @@ -78,6 +78,7 @@ void blk_activate(BlockBackend *blk, Error **errp); int blk_make_zero(BlockBackend *blk, BdrvRequestFlags flags); void blk_aio_cancel(BlockAIOCB *acb); int blk_commit_all(void); +bool blk_in_drain(BlockBackend *blk); void blk_drain(BlockBackend *blk); void blk_drain_all(void); void blk_set_on_error(BlockBackend *blk, BlockdevOnError on_read_error, diff --git a/block/block-backend.c b/block/block-backend.c index 68d38635bc..96f03cae95 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -1270,6 +1270,13 @@ blk_check_byte_request(BlockBackend *blk, int64_t offset, int64_t bytes) return 0; } +/* Are we currently in a drained section? */ +bool blk_in_drain(BlockBackend *blk) +{ + GLOBAL_STATE_CODE(); /* change to IO_OR_GS_CODE(), if necessary */ + return qatomic_read(&blk->quiesce_counter); +} + /* To be called between exactly one pair of blk_inc/dec_in_flight() */ static void coroutine_fn blk_wait_while_drained(BlockBackend *blk) { From patchwork Thu May 4 19:53:17 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 13231714 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 7959BC77B78 for ; Thu, 4 May 2023 19:54:20 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.530079.825433 (Exim 4.92) (envelope-from ) id 1puf1m-0007We-B9; Thu, 04 May 2023 19:54:10 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 530079.825433; Thu, 04 May 2023 19:54:10 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf1m-0007V5-1A; Thu, 04 May 2023 19:54:10 +0000 Received: by outflank-mailman (input) for mailman id 530079; Thu, 04 May 2023 19:54:08 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf1k-0003xx-DI for xen-devel@lists.xenproject.org; Thu, 04 May 2023 19:54:08 +0000 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 6c75c70b-eab5-11ed-8611-37d641c3527e; Thu, 04 May 2023 21:54:05 +0200 (CEST) Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-83-mf16-bP3ON6rSVB1WZdIzA-1; Thu, 04 May 2023 15:54:00 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.rdu2.redhat.com [10.11.54.2]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id E5EB4101A531; Thu, 4 May 2023 19:53:58 +0000 (UTC) Received: from localhost (unknown [10.39.192.57]) by smtp.corp.redhat.com (Postfix) with ESMTP id 00AB54020962; Thu, 4 May 2023 19:53:57 +0000 (UTC) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 6c75c70b-eab5-11ed-8611-37d641c3527e DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1683230044; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=TaJhEzn2xnk+TJZ+4gZYO3ndhDET6IVJHLdTW4Bnkp0=; b=OkR7Xgyrk9DRZ+GmfacqrWgXZ781Uwvtp77CWlpRDdaciJmLhCObMpDc78EIFyvv4qQ1ri 3co3ZB8Ber+KuqHQ91JXqRvsszqqCjSqyy5DNy+AQWoc286ncoAKHFaduZxCZOgSSONzv2 nGIRnXaUVCCnmXlw8aCYF7LfwZMNhmc= X-MC-Unique: mf16-bP3ON6rSVB1WZdIzA-1 From: Stefan Hajnoczi To: qemu-devel@nongnu.org Cc: Ronnie Sahlberg , Aarushi Mehta , qemu-block@nongnu.org, Paul Durrant , Anthony Perard , Peter Lieven , Stefan Weil , Xie Yongji , Kevin Wolf , Paolo Bonzini , "Michael S. Tsirkin" , Leonardo Bras , Peter Xu , Hanna Reitz , Stefano Stabellini , Richard Henderson , David Woodhouse , Coiby Xu , Eduardo Habkost , Stefano Garzarella , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , Stefan Hajnoczi , Julia Suvorova , xen-devel@lists.xenproject.org, eesposit@redhat.com, Juan Quintela , "Richard W.M. Jones" , Fam Zheng , Marcel Apfelbaum Subject: [PATCH v5 11/21] block: drain from main loop thread in bdrv_co_yield_to_drain() Date: Thu, 4 May 2023 15:53:17 -0400 Message-Id: <20230504195327.695107-12-stefanha@redhat.com> In-Reply-To: <20230504195327.695107-1-stefanha@redhat.com> References: <20230504195327.695107-1-stefanha@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.2 For simplicity, always run BlockDevOps .drained_begin/end/poll() callbacks in the main loop thread. This makes it easier to implement the callbacks and avoids extra locks. Move the function pointer declarations from the I/O Code section to the Global State section for BlockDevOps, BdrvChildClass, and BlockDriver. Narrow IO_OR_GS_CODE() to GLOBAL_STATE_CODE() where appropriate. The test-bdrv-drain test case calls bdrv_drain() from an IOThread. This is now only allowed from coroutine context, so update the test case to run in a coroutine. Signed-off-by: Stefan Hajnoczi --- include/block/block_int-common.h | 90 +++++++++++++-------------- include/sysemu/block-backend-common.h | 25 ++++---- block/io.c | 14 +++-- tests/unit/test-bdrv-drain.c | 14 +++-- 4 files changed, 76 insertions(+), 67 deletions(-) diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h index 013d419444..f462a8be55 100644 --- a/include/block/block_int-common.h +++ b/include/block/block_int-common.h @@ -356,6 +356,21 @@ struct BlockDriver { void (*bdrv_attach_aio_context)(BlockDriverState *bs, AioContext *new_context); + /** + * bdrv_drain_begin is called if implemented in the beginning of a + * drain operation to drain and stop any internal sources of requests in + * the driver. + * bdrv_drain_end is called if implemented at the end of the drain. + * + * They should be used by the driver to e.g. manage scheduled I/O + * requests, or toggle an internal state. After the end of the drain new + * requests will continue normally. + * + * Implementations of both functions must not call aio_poll(). + */ + void (*bdrv_drain_begin)(BlockDriverState *bs); + void (*bdrv_drain_end)(BlockDriverState *bs); + /** * Try to get @bs's logical and physical block size. * On success, store them in @bsz and return zero. @@ -743,21 +758,6 @@ struct BlockDriver { void coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_io_unplug)( BlockDriverState *bs); - /** - * bdrv_drain_begin is called if implemented in the beginning of a - * drain operation to drain and stop any internal sources of requests in - * the driver. - * bdrv_drain_end is called if implemented at the end of the drain. - * - * They should be used by the driver to e.g. manage scheduled I/O - * requests, or toggle an internal state. After the end of the drain new - * requests will continue normally. - * - * Implementations of both functions must not call aio_poll(). - */ - void (*bdrv_drain_begin)(BlockDriverState *bs); - void (*bdrv_drain_end)(BlockDriverState *bs); - bool (*bdrv_supports_persistent_dirty_bitmap)(BlockDriverState *bs); bool coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_can_store_new_dirty_bitmap)( @@ -920,36 +920,6 @@ struct BdrvChildClass { void GRAPH_WRLOCK_PTR (*attach)(BdrvChild *child); void GRAPH_WRLOCK_PTR (*detach)(BdrvChild *child); - /* - * Notifies the parent that the filename of its child has changed (e.g. - * because the direct child was removed from the backing chain), so that it - * can update its reference. - */ - int (*update_filename)(BdrvChild *child, BlockDriverState *new_base, - const char *filename, Error **errp); - - bool (*change_aio_ctx)(BdrvChild *child, AioContext *ctx, - GHashTable *visited, Transaction *tran, - Error **errp); - - /* - * I/O API functions. These functions are thread-safe. - * - * See include/block/block-io.h for more information about - * the I/O API. - */ - - void (*resize)(BdrvChild *child); - - /* - * Returns a name that is supposedly more useful for human users than the - * node name for identifying the node in question (in particular, a BB - * name), or NULL if the parent can't provide a better name. - */ - const char *(*get_name)(BdrvChild *child); - - AioContext *(*get_parent_aio_context)(BdrvChild *child); - /* * If this pair of functions is implemented, the parent doesn't issue new * requests after returning from .drained_begin() until .drained_end() is @@ -970,6 +940,36 @@ struct BdrvChildClass { * activity on the child has stopped. */ bool (*drained_poll)(BdrvChild *child); + + /* + * Notifies the parent that the filename of its child has changed (e.g. + * because the direct child was removed from the backing chain), so that it + * can update its reference. + */ + int (*update_filename)(BdrvChild *child, BlockDriverState *new_base, + const char *filename, Error **errp); + + bool (*change_aio_ctx)(BdrvChild *child, AioContext *ctx, + GHashTable *visited, Transaction *tran, + Error **errp); + + /* + * I/O API functions. These functions are thread-safe. + * + * See include/block/block-io.h for more information about + * the I/O API. + */ + + void (*resize)(BdrvChild *child); + + /* + * Returns a name that is supposedly more useful for human users than the + * node name for identifying the node in question (in particular, a BB + * name), or NULL if the parent can't provide a better name. + */ + const char *(*get_name)(BdrvChild *child); + + AioContext *(*get_parent_aio_context)(BdrvChild *child); }; extern const BdrvChildClass child_of_bds; diff --git a/include/sysemu/block-backend-common.h b/include/sysemu/block-backend-common.h index 2391679c56..780cea7305 100644 --- a/include/sysemu/block-backend-common.h +++ b/include/sysemu/block-backend-common.h @@ -59,6 +59,19 @@ typedef struct BlockDevOps { */ bool (*is_medium_locked)(void *opaque); + /* + * Runs when the backend receives a drain request. + */ + void (*drained_begin)(void *opaque); + /* + * Runs when the backend's last drain request ends. + */ + void (*drained_end)(void *opaque); + /* + * Is the device still busy? + */ + bool (*drained_poll)(void *opaque); + /* * I/O API functions. These functions are thread-safe. * @@ -76,18 +89,6 @@ typedef struct BlockDevOps { * Runs when the size changed (e.g. monitor command block_resize) */ void (*resize_cb)(void *opaque); - /* - * Runs when the backend receives a drain request. - */ - void (*drained_begin)(void *opaque); - /* - * Runs when the backend's last drain request ends. - */ - void (*drained_end)(void *opaque); - /* - * Is the device still busy? - */ - bool (*drained_poll)(void *opaque); } BlockDevOps; /* diff --git a/block/io.c b/block/io.c index 6fa1993374..532c8c90c9 100644 --- a/block/io.c +++ b/block/io.c @@ -60,7 +60,7 @@ static void bdrv_parent_drained_begin(BlockDriverState *bs, BdrvChild *ignore) void bdrv_parent_drained_end_single(BdrvChild *c) { - IO_OR_GS_CODE(); + GLOBAL_STATE_CODE(); assert(c->quiesced_parent); c->quiesced_parent = false; @@ -108,7 +108,7 @@ static bool bdrv_parent_drained_poll(BlockDriverState *bs, BdrvChild *ignore, void bdrv_parent_drained_begin_single(BdrvChild *c) { - IO_OR_GS_CODE(); + GLOBAL_STATE_CODE(); assert(!c->quiesced_parent); c->quiesced_parent = true; @@ -248,7 +248,7 @@ typedef struct { bool bdrv_drain_poll(BlockDriverState *bs, BdrvChild *ignore_parent, bool ignore_bds_parents) { - IO_OR_GS_CODE(); + GLOBAL_STATE_CODE(); if (bdrv_parent_drained_poll(bs, ignore_parent, ignore_bds_parents)) { return true; @@ -335,7 +335,8 @@ static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs, if (ctx != co_ctx) { aio_context_release(ctx); } - replay_bh_schedule_oneshot_event(ctx, bdrv_co_drain_bh_cb, &data); + replay_bh_schedule_oneshot_event(qemu_get_aio_context(), + bdrv_co_drain_bh_cb, &data); qemu_coroutine_yield(); /* If we are resumed from some other event (such as an aio completion or a @@ -358,6 +359,8 @@ static void bdrv_do_drained_begin(BlockDriverState *bs, BdrvChild *parent, return; } + GLOBAL_STATE_CODE(); + /* Stop things in parent-to-child order */ if (qatomic_fetch_inc(&bs->quiesce_counter) == 0) { aio_disable_external(bdrv_get_aio_context(bs)); @@ -400,11 +403,14 @@ static void bdrv_do_drained_end(BlockDriverState *bs, BdrvChild *parent) { int old_quiesce_counter; + IO_OR_GS_CODE(); + if (qemu_in_coroutine()) { bdrv_co_yield_to_drain(bs, false, parent, false); return; } assert(bs->quiesce_counter > 0); + GLOBAL_STATE_CODE(); /* Re-enable things in child-to-parent order */ old_quiesce_counter = qatomic_fetch_dec(&bs->quiesce_counter); diff --git a/tests/unit/test-bdrv-drain.c b/tests/unit/test-bdrv-drain.c index d9d3807062..dc3cb9e0e3 100644 --- a/tests/unit/test-bdrv-drain.c +++ b/tests/unit/test-bdrv-drain.c @@ -445,19 +445,19 @@ struct test_iothread_data { BlockDriverState *bs; enum drain_type drain_type; int *aio_ret; + bool co_done; }; -static void test_iothread_drain_entry(void *opaque) +static void coroutine_fn test_iothread_drain_co_entry(void *opaque) { struct test_iothread_data *data = opaque; - aio_context_acquire(bdrv_get_aio_context(data->bs)); do_drain_begin(data->drain_type, data->bs); g_assert_cmpint(*data->aio_ret, ==, 0); do_drain_end(data->drain_type, data->bs); - aio_context_release(bdrv_get_aio_context(data->bs)); - qemu_event_set(&done_event); + data->co_done = true; + aio_wait_kick(); } static void test_iothread_aio_cb(void *opaque, int ret) @@ -493,6 +493,7 @@ static void test_iothread_common(enum drain_type drain_type, int drain_thread) BlockDriverState *bs; BDRVTestState *s; BlockAIOCB *acb; + Coroutine *co; int aio_ret; struct test_iothread_data data; @@ -571,8 +572,9 @@ static void test_iothread_common(enum drain_type drain_type, int drain_thread) } break; case 1: - aio_bh_schedule_oneshot(ctx_a, test_iothread_drain_entry, &data); - qemu_event_wait(&done_event); + co = qemu_coroutine_create(test_iothread_drain_co_entry, &data); + aio_co_enter(ctx_a, co); + AIO_WAIT_WHILE_UNLOCKED(NULL, !data.co_done); break; default: g_assert_not_reached(); From patchwork Thu May 4 19:53:18 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 13231753 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D7BEEC7EE21 for ; Thu, 4 May 2023 20:00:42 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.530118.825523 (Exim 4.92) (envelope-from ) id 1puf7e-0006HF-Dd; Thu, 04 May 2023 20:00:14 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 530118.825523; Thu, 04 May 2023 20:00:14 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf7e-0006GM-9J; Thu, 04 May 2023 20:00:14 +0000 Received: by outflank-mailman (input) for mailman id 530118; Thu, 04 May 2023 20:00:13 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf1m-0003xx-S4 for xen-devel@lists.xenproject.org; Thu, 04 May 2023 19:54:10 +0000 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 6e900e4a-eab5-11ed-8611-37d641c3527e; Thu, 04 May 2023 21:54:09 +0200 (CEST) Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-288-xmcew5b9Mi60YoS0X3Y-pA-1; Thu, 04 May 2023 15:54:02 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 92EA73813F37; Thu, 4 May 2023 19:54:01 +0000 (UTC) Received: from localhost (unknown [10.39.192.57]) by smtp.corp.redhat.com (Postfix) with ESMTP id EB53F2166B31; Thu, 4 May 2023 19:54:00 +0000 (UTC) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 6e900e4a-eab5-11ed-8611-37d641c3527e DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1683230048; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=UIROaLBR9j1PhaubFnxgRi7zZWyl4fJ5E1s3DXvyvk4=; b=RZA3vtrpky9fDgrT/OCu2Bro0R+jwMqhXEhxJI57kEGG1bb1HRtp8T5OtXqQyW4MwN+Jj/ 5MqnLrs8dBLqB3Vw6dVg1YdYQh0AprySzX/mPCeuT0XkJm3Y79a5vsDJWYumGygtwnGEfW cyoCsuo35ds39gchqgIU6UQoTdtv6Q0= X-MC-Unique: xmcew5b9Mi60YoS0X3Y-pA-1 From: Stefan Hajnoczi To: qemu-devel@nongnu.org Cc: Ronnie Sahlberg , Aarushi Mehta , qemu-block@nongnu.org, Paul Durrant , Anthony Perard , Peter Lieven , Stefan Weil , Xie Yongji , Kevin Wolf , Paolo Bonzini , "Michael S. Tsirkin" , Leonardo Bras , Peter Xu , Hanna Reitz , Stefano Stabellini , Richard Henderson , David Woodhouse , Coiby Xu , Eduardo Habkost , Stefano Garzarella , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , Stefan Hajnoczi , Julia Suvorova , xen-devel@lists.xenproject.org, eesposit@redhat.com, Juan Quintela , "Richard W.M. Jones" , Fam Zheng , Marcel Apfelbaum Subject: [PATCH v5 12/21] xen-block: implement BlockDevOps->drained_begin() Date: Thu, 4 May 2023 15:53:18 -0400 Message-Id: <20230504195327.695107-13-stefanha@redhat.com> In-Reply-To: <20230504195327.695107-1-stefanha@redhat.com> References: <20230504195327.695107-1-stefanha@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 Detach event channels during drained sections to stop I/O submission from the ring. xen-block is no longer reliant on aio_disable_external() after this patch. This will allow us to remove the aio_disable_external() API once all other code that relies on it is converted. Extend xen_device_set_event_channel_context() to allow ctx=NULL. The event channel still exists but the event loop does not monitor the file descriptor. Event channel processing can resume by calling xen_device_set_event_channel_context() with a non-NULL ctx. Factor out xen_device_set_event_channel_context() calls in hw/block/dataplane/xen-block.c into attach/detach helper functions. Incidentally, these don't require the AioContext lock because aio_set_fd_handler() is thread-safe. It's safer to register BlockDevOps after the dataplane instance has been created. The BlockDevOps .drained_begin/end() callbacks depend on the dataplane instance, so move the blk_set_dev_ops() call after xen_block_dataplane_create(). Signed-off-by: Stefan Hajnoczi Reviewed-by: Anthony PERARD --- hw/block/dataplane/xen-block.h | 2 ++ hw/block/dataplane/xen-block.c | 42 +++++++++++++++++++++++++--------- hw/block/xen-block.c | 24 ++++++++++++++++--- hw/xen/xen-bus.c | 7 ++++-- 4 files changed, 59 insertions(+), 16 deletions(-) diff --git a/hw/block/dataplane/xen-block.h b/hw/block/dataplane/xen-block.h index 76dcd51c3d..7b8e9df09f 100644 --- a/hw/block/dataplane/xen-block.h +++ b/hw/block/dataplane/xen-block.h @@ -26,5 +26,7 @@ void xen_block_dataplane_start(XenBlockDataPlane *dataplane, unsigned int protocol, Error **errp); void xen_block_dataplane_stop(XenBlockDataPlane *dataplane); +void xen_block_dataplane_attach(XenBlockDataPlane *dataplane); +void xen_block_dataplane_detach(XenBlockDataPlane *dataplane); #endif /* HW_BLOCK_DATAPLANE_XEN_BLOCK_H */ diff --git a/hw/block/dataplane/xen-block.c b/hw/block/dataplane/xen-block.c index d8bc39d359..2597f38805 100644 --- a/hw/block/dataplane/xen-block.c +++ b/hw/block/dataplane/xen-block.c @@ -664,6 +664,30 @@ void xen_block_dataplane_destroy(XenBlockDataPlane *dataplane) g_free(dataplane); } +void xen_block_dataplane_detach(XenBlockDataPlane *dataplane) +{ + if (!dataplane || !dataplane->event_channel) { + return; + } + + /* Only reason for failure is a NULL channel */ + xen_device_set_event_channel_context(dataplane->xendev, + dataplane->event_channel, + NULL, &error_abort); +} + +void xen_block_dataplane_attach(XenBlockDataPlane *dataplane) +{ + if (!dataplane || !dataplane->event_channel) { + return; + } + + /* Only reason for failure is a NULL channel */ + xen_device_set_event_channel_context(dataplane->xendev, + dataplane->event_channel, + dataplane->ctx, &error_abort); +} + void xen_block_dataplane_stop(XenBlockDataPlane *dataplane) { XenDevice *xendev; @@ -674,13 +698,11 @@ void xen_block_dataplane_stop(XenBlockDataPlane *dataplane) xendev = dataplane->xendev; - aio_context_acquire(dataplane->ctx); - if (dataplane->event_channel) { - /* Only reason for failure is a NULL channel */ - xen_device_set_event_channel_context(xendev, dataplane->event_channel, - qemu_get_aio_context(), - &error_abort); + if (!blk_in_drain(dataplane->blk)) { + xen_block_dataplane_detach(dataplane); } + + aio_context_acquire(dataplane->ctx); /* Xen doesn't have multiple users for nodes, so this can't fail */ blk_set_aio_context(dataplane->blk, qemu_get_aio_context(), &error_abort); aio_context_release(dataplane->ctx); @@ -819,11 +841,9 @@ void xen_block_dataplane_start(XenBlockDataPlane *dataplane, blk_set_aio_context(dataplane->blk, dataplane->ctx, NULL); aio_context_release(old_context); - /* Only reason for failure is a NULL channel */ - aio_context_acquire(dataplane->ctx); - xen_device_set_event_channel_context(xendev, dataplane->event_channel, - dataplane->ctx, &error_abort); - aio_context_release(dataplane->ctx); + if (!blk_in_drain(dataplane->blk)) { + xen_block_dataplane_attach(dataplane); + } return; diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c index f5a744589d..f099914831 100644 --- a/hw/block/xen-block.c +++ b/hw/block/xen-block.c @@ -189,8 +189,26 @@ static void xen_block_resize_cb(void *opaque) xen_device_backend_printf(xendev, "state", "%u", state); } +/* Suspend request handling */ +static void xen_block_drained_begin(void *opaque) +{ + XenBlockDevice *blockdev = opaque; + + xen_block_dataplane_detach(blockdev->dataplane); +} + +/* Resume request handling */ +static void xen_block_drained_end(void *opaque) +{ + XenBlockDevice *blockdev = opaque; + + xen_block_dataplane_attach(blockdev->dataplane); +} + static const BlockDevOps xen_block_dev_ops = { - .resize_cb = xen_block_resize_cb, + .resize_cb = xen_block_resize_cb, + .drained_begin = xen_block_drained_begin, + .drained_end = xen_block_drained_end, }; static void xen_block_realize(XenDevice *xendev, Error **errp) @@ -242,8 +260,6 @@ static void xen_block_realize(XenDevice *xendev, Error **errp) return; } - blk_set_dev_ops(blk, &xen_block_dev_ops, blockdev); - if (conf->discard_granularity == -1) { conf->discard_granularity = conf->physical_block_size; } @@ -277,6 +293,8 @@ static void xen_block_realize(XenDevice *xendev, Error **errp) blockdev->dataplane = xen_block_dataplane_create(xendev, blk, conf->logical_block_size, blockdev->props.iothread); + + blk_set_dev_ops(blk, &xen_block_dev_ops, blockdev); } static void xen_block_frontend_changed(XenDevice *xendev, diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c index c59850b1de..b8f408c9ed 100644 --- a/hw/xen/xen-bus.c +++ b/hw/xen/xen-bus.c @@ -846,8 +846,11 @@ void xen_device_set_event_channel_context(XenDevice *xendev, NULL, NULL, NULL, NULL, NULL); channel->ctx = ctx; - aio_set_fd_handler(channel->ctx, qemu_xen_evtchn_fd(channel->xeh), true, - xen_device_event, NULL, xen_device_poll, NULL, channel); + if (ctx) { + aio_set_fd_handler(channel->ctx, qemu_xen_evtchn_fd(channel->xeh), + true, xen_device_event, NULL, xen_device_poll, NULL, + channel); + } } XenEventChannel *xen_device_bind_event_channel(XenDevice *xendev, From patchwork Thu May 4 19:53:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 13231752 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id E6622C77B78 for ; Thu, 4 May 2023 20:00:43 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.530119.825536 (Exim 4.92) (envelope-from ) id 1puf7o-00071W-0M; Thu, 04 May 2023 20:00:24 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 530119.825536; Thu, 04 May 2023 20:00:23 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf7n-00071K-QB; Thu, 04 May 2023 20:00:23 +0000 Received: by outflank-mailman (input) for mailman id 530119; Thu, 04 May 2023 20:00:22 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf1p-0003iB-Sq for xen-devel@lists.xenproject.org; Thu, 04 May 2023 19:54:13 +0000 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 70e1dc82-eab5-11ed-b226-6b7b168915f2; Thu, 04 May 2023 21:54:13 +0200 (CEST) Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-310-3JUPVKmDMRukKNbAGsy8rA-1; Thu, 04 May 2023 15:54:05 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 0DD063C0F428; Thu, 4 May 2023 19:54:04 +0000 (UTC) Received: from localhost (unknown [10.39.192.57]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4EFA440C2064; Thu, 4 May 2023 19:54:03 +0000 (UTC) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 70e1dc82-eab5-11ed-b226-6b7b168915f2 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1683230052; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=YdqEYBGejD/PzTlXIgNRYCDgy4cvOgGgt6P2aeMbPY4=; b=iyJcOHhilUt2NLAzURmkERRvO0JXlScy+ZPZep5yEoHWgGyqGCYSTF77mBk1P1Us+qHjhs euIsShwn60iDjftuacIjG1RBffK8hxz2GGLK9NL8xilQ1byxzxlBWm+ps750DjxVouwB14 EPVkEEJZ23T2Vl0JU12uqwI/V5qBvsg= X-MC-Unique: 3JUPVKmDMRukKNbAGsy8rA-1 From: Stefan Hajnoczi To: qemu-devel@nongnu.org Cc: Ronnie Sahlberg , Aarushi Mehta , qemu-block@nongnu.org, Paul Durrant , Anthony Perard , Peter Lieven , Stefan Weil , Xie Yongji , Kevin Wolf , Paolo Bonzini , "Michael S. Tsirkin" , Leonardo Bras , Peter Xu , Hanna Reitz , Stefano Stabellini , Richard Henderson , David Woodhouse , Coiby Xu , Eduardo Habkost , Stefano Garzarella , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , Stefan Hajnoczi , Julia Suvorova , xen-devel@lists.xenproject.org, eesposit@redhat.com, Juan Quintela , "Richard W.M. Jones" , Fam Zheng , Marcel Apfelbaum Subject: [PATCH v5 13/21] hw/xen: do not set is_external=true on evtchn fds Date: Thu, 4 May 2023 15:53:19 -0400 Message-Id: <20230504195327.695107-14-stefanha@redhat.com> In-Reply-To: <20230504195327.695107-1-stefanha@redhat.com> References: <20230504195327.695107-1-stefanha@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.1 is_external=true suspends fd handlers between aio_disable_external() and aio_enable_external(). The block layer's drain operation uses this mechanism to prevent new I/O from sneaking in between bdrv_drained_begin() and bdrv_drained_end(). The previous commit converted the xen-block device to use BlockDevOps .drained_begin/end() callbacks. It no longer relies on is_external=true so it is safe to pass is_external=false. This is part of ongoing work to remove the aio_disable_external() API. Signed-off-by: Stefan Hajnoczi Acked-by: Anthony PERARD --- hw/xen/xen-bus.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c index b8f408c9ed..bf256d4da2 100644 --- a/hw/xen/xen-bus.c +++ b/hw/xen/xen-bus.c @@ -842,14 +842,14 @@ void xen_device_set_event_channel_context(XenDevice *xendev, } if (channel->ctx) - aio_set_fd_handler(channel->ctx, qemu_xen_evtchn_fd(channel->xeh), true, + aio_set_fd_handler(channel->ctx, qemu_xen_evtchn_fd(channel->xeh), false, NULL, NULL, NULL, NULL, NULL); channel->ctx = ctx; if (ctx) { aio_set_fd_handler(channel->ctx, qemu_xen_evtchn_fd(channel->xeh), - true, xen_device_event, NULL, xen_device_poll, NULL, - channel); + false, xen_device_event, NULL, xen_device_poll, + NULL, channel); } } @@ -923,7 +923,7 @@ void xen_device_unbind_event_channel(XenDevice *xendev, QLIST_REMOVE(channel, list); - aio_set_fd_handler(channel->ctx, qemu_xen_evtchn_fd(channel->xeh), true, + aio_set_fd_handler(channel->ctx, qemu_xen_evtchn_fd(channel->xeh), false, NULL, NULL, NULL, NULL, NULL); if (qemu_xen_evtchn_unbind(channel->xeh, channel->local_port) < 0) { From patchwork Thu May 4 19:53:20 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 13231747 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B8567C7EE21 for ; Thu, 4 May 2023 19:59:52 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.530095.825466 (Exim 4.92) (envelope-from ) id 1puf6s-0002hr-Gx; Thu, 04 May 2023 19:59:26 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 530095.825466; Thu, 04 May 2023 19:59:26 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf6s-0002hf-DY; Thu, 04 May 2023 19:59:26 +0000 Received: by outflank-mailman (input) for mailman id 530095; Thu, 04 May 2023 19:59:24 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf1q-0003xx-Dp for xen-devel@lists.xenproject.org; Thu, 04 May 2023 19:54:14 +0000 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 708d161a-eab5-11ed-8611-37d641c3527e; Thu, 04 May 2023 21:54:12 +0200 (CEST) Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-127-Vlp1VFRtMiyjJOAA8uYRjg-1; Thu, 04 May 2023 15:54:08 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 66842A0F392; Thu, 4 May 2023 19:54:06 +0000 (UTC) Received: from localhost (unknown [10.39.192.57]) by smtp.corp.redhat.com (Postfix) with ESMTP id BD6032166B31; Thu, 4 May 2023 19:54:05 +0000 (UTC) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 708d161a-eab5-11ed-8611-37d641c3527e DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1683230051; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=7wSWNHCOtGu2HSsa9w9EnU6dW7eXmRIvTEr1l03At9A=; b=P9zEgIFjfrIgZ6OZCMauqbsLsASBuwBcr2L8tmHqwgKmN+dxLLl4f5JGOhRZOxG8Xl4FPY 01BueEG9KicSVoimaf53qGONqV0LEYkz1RmOw0jWfCIUnlrKajMNHFEAZqxOXvmb395TnP AubLXFXnVK5i6lI7TKU4dztP69/Y4R0= X-MC-Unique: Vlp1VFRtMiyjJOAA8uYRjg-1 From: Stefan Hajnoczi To: qemu-devel@nongnu.org Cc: Ronnie Sahlberg , Aarushi Mehta , qemu-block@nongnu.org, Paul Durrant , Anthony Perard , Peter Lieven , Stefan Weil , Xie Yongji , Kevin Wolf , Paolo Bonzini , "Michael S. Tsirkin" , Leonardo Bras , Peter Xu , Hanna Reitz , Stefano Stabellini , Richard Henderson , David Woodhouse , Coiby Xu , Eduardo Habkost , Stefano Garzarella , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , Stefan Hajnoczi , Julia Suvorova , xen-devel@lists.xenproject.org, eesposit@redhat.com, Juan Quintela , "Richard W.M. Jones" , Fam Zheng , Marcel Apfelbaum Subject: [PATCH v5 14/21] block/export: rewrite vduse-blk drain code Date: Thu, 4 May 2023 15:53:20 -0400 Message-Id: <20230504195327.695107-15-stefanha@redhat.com> In-Reply-To: <20230504195327.695107-1-stefanha@redhat.com> References: <20230504195327.695107-1-stefanha@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 vduse_blk_detach_ctx() waits for in-flight requests using AIO_WAIT_WHILE(). This is not allowed according to a comment in bdrv_set_aio_context_commit(): /* * Take the old AioContex when detaching it from bs. * At this point, new_context lock is already acquired, and we are now * also taking old_context. This is safe as long as bdrv_detach_aio_context * does not call AIO_POLL_WHILE(). */ Use this opportunity to rewrite the drain code in vduse-blk: - Use the BlockExport refcount so that vduse_blk_exp_delete() is only called when there are no more requests in flight. - Implement .drained_poll() so in-flight request coroutines are stopped by the time .bdrv_detach_aio_context() is called. - Remove AIO_WAIT_WHILE() from vduse_blk_detach_ctx() to solve the .bdrv_detach_aio_context() constraint violation. It's no longer needed due to the previous changes. - Always handle the VDUSE file descriptor, even in drained sections. The VDUSE file descriptor doesn't submit I/O, so it's safe to handle it in drained sections. This ensures that the VDUSE kernel code gets a fast response. - Suspend virtqueue fd handlers in .drained_begin() and resume them in .drained_end(). This eliminates the need for the aio_set_fd_handler(is_external=true) flag, which is being removed from QEMU. This is a long list but splitting it into individual commits would probably lead to git bisect failures - the changes are all related. Signed-off-by: Stefan Hajnoczi --- block/export/vduse-blk.c | 132 +++++++++++++++++++++++++++------------ 1 file changed, 93 insertions(+), 39 deletions(-) diff --git a/block/export/vduse-blk.c b/block/export/vduse-blk.c index b53ef39da0..a25556fe04 100644 --- a/block/export/vduse-blk.c +++ b/block/export/vduse-blk.c @@ -31,7 +31,8 @@ typedef struct VduseBlkExport { VduseDev *dev; uint16_t num_queues; char *recon_file; - unsigned int inflight; + unsigned int inflight; /* atomic */ + bool vqs_started; } VduseBlkExport; typedef struct VduseBlkReq { @@ -41,13 +42,24 @@ typedef struct VduseBlkReq { static void vduse_blk_inflight_inc(VduseBlkExport *vblk_exp) { - vblk_exp->inflight++; + if (qatomic_fetch_inc(&vblk_exp->inflight) == 0) { + /* Prevent export from being deleted */ + aio_context_acquire(vblk_exp->export.ctx); + blk_exp_ref(&vblk_exp->export); + aio_context_release(vblk_exp->export.ctx); + } } static void vduse_blk_inflight_dec(VduseBlkExport *vblk_exp) { - if (--vblk_exp->inflight == 0) { + if (qatomic_fetch_dec(&vblk_exp->inflight) == 1) { + /* Wake AIO_WAIT_WHILE() */ aio_wait_kick(); + + /* Now the export can be deleted */ + aio_context_acquire(vblk_exp->export.ctx); + blk_exp_unref(&vblk_exp->export); + aio_context_release(vblk_exp->export.ctx); } } @@ -124,8 +136,12 @@ static void vduse_blk_enable_queue(VduseDev *dev, VduseVirtq *vq) { VduseBlkExport *vblk_exp = vduse_dev_get_priv(dev); + if (!vblk_exp->vqs_started) { + return; /* vduse_blk_drained_end() will start vqs later */ + } + aio_set_fd_handler(vblk_exp->export.ctx, vduse_queue_get_fd(vq), - true, on_vduse_vq_kick, NULL, NULL, NULL, vq); + false, on_vduse_vq_kick, NULL, NULL, NULL, vq); /* Make sure we don't miss any kick afer reconnecting */ eventfd_write(vduse_queue_get_fd(vq), 1); } @@ -133,9 +149,14 @@ static void vduse_blk_enable_queue(VduseDev *dev, VduseVirtq *vq) static void vduse_blk_disable_queue(VduseDev *dev, VduseVirtq *vq) { VduseBlkExport *vblk_exp = vduse_dev_get_priv(dev); + int fd = vduse_queue_get_fd(vq); - aio_set_fd_handler(vblk_exp->export.ctx, vduse_queue_get_fd(vq), - true, NULL, NULL, NULL, NULL, NULL); + if (fd < 0) { + return; + } + + aio_set_fd_handler(vblk_exp->export.ctx, fd, false, + NULL, NULL, NULL, NULL, NULL); } static const VduseOps vduse_blk_ops = { @@ -152,42 +173,19 @@ static void on_vduse_dev_kick(void *opaque) static void vduse_blk_attach_ctx(VduseBlkExport *vblk_exp, AioContext *ctx) { - int i; - aio_set_fd_handler(vblk_exp->export.ctx, vduse_dev_get_fd(vblk_exp->dev), - true, on_vduse_dev_kick, NULL, NULL, NULL, + false, on_vduse_dev_kick, NULL, NULL, NULL, vblk_exp->dev); - for (i = 0; i < vblk_exp->num_queues; i++) { - VduseVirtq *vq = vduse_dev_get_queue(vblk_exp->dev, i); - int fd = vduse_queue_get_fd(vq); - - if (fd < 0) { - continue; - } - aio_set_fd_handler(vblk_exp->export.ctx, fd, true, - on_vduse_vq_kick, NULL, NULL, NULL, vq); - } + /* Virtqueues are handled by vduse_blk_drained_end() */ } static void vduse_blk_detach_ctx(VduseBlkExport *vblk_exp) { - int i; - - for (i = 0; i < vblk_exp->num_queues; i++) { - VduseVirtq *vq = vduse_dev_get_queue(vblk_exp->dev, i); - int fd = vduse_queue_get_fd(vq); - - if (fd < 0) { - continue; - } - aio_set_fd_handler(vblk_exp->export.ctx, fd, - true, NULL, NULL, NULL, NULL, NULL); - } aio_set_fd_handler(vblk_exp->export.ctx, vduse_dev_get_fd(vblk_exp->dev), - true, NULL, NULL, NULL, NULL, NULL); + false, NULL, NULL, NULL, NULL, NULL); - AIO_WAIT_WHILE(vblk_exp->export.ctx, vblk_exp->inflight > 0); + /* Virtqueues are handled by vduse_blk_drained_begin() */ } @@ -220,8 +218,55 @@ static void vduse_blk_resize(void *opaque) (char *)&config.capacity); } +static void vduse_blk_stop_virtqueues(VduseBlkExport *vblk_exp) +{ + for (uint16_t i = 0; i < vblk_exp->num_queues; i++) { + VduseVirtq *vq = vduse_dev_get_queue(vblk_exp->dev, i); + vduse_blk_disable_queue(vblk_exp->dev, vq); + } + + vblk_exp->vqs_started = false; +} + +static void vduse_blk_start_virtqueues(VduseBlkExport *vblk_exp) +{ + vblk_exp->vqs_started = true; + + for (uint16_t i = 0; i < vblk_exp->num_queues; i++) { + VduseVirtq *vq = vduse_dev_get_queue(vblk_exp->dev, i); + vduse_blk_enable_queue(vblk_exp->dev, vq); + } +} + +static void vduse_blk_drained_begin(void *opaque) +{ + BlockExport *exp = opaque; + VduseBlkExport *vblk_exp = container_of(exp, VduseBlkExport, export); + + vduse_blk_stop_virtqueues(vblk_exp); +} + +static void vduse_blk_drained_end(void *opaque) +{ + BlockExport *exp = opaque; + VduseBlkExport *vblk_exp = container_of(exp, VduseBlkExport, export); + + vduse_blk_start_virtqueues(vblk_exp); +} + +static bool vduse_blk_drained_poll(void *opaque) +{ + BlockExport *exp = opaque; + VduseBlkExport *vblk_exp = container_of(exp, VduseBlkExport, export); + + return qatomic_read(&vblk_exp->inflight) > 0; +} + static const BlockDevOps vduse_block_ops = { - .resize_cb = vduse_blk_resize, + .resize_cb = vduse_blk_resize, + .drained_begin = vduse_blk_drained_begin, + .drained_end = vduse_blk_drained_end, + .drained_poll = vduse_blk_drained_poll, }; static int vduse_blk_exp_create(BlockExport *exp, BlockExportOptions *opts, @@ -268,6 +313,7 @@ static int vduse_blk_exp_create(BlockExport *exp, BlockExportOptions *opts, vblk_exp->handler.serial = g_strdup(vblk_opts->serial ?: ""); vblk_exp->handler.logical_block_size = logical_block_size; vblk_exp->handler.writable = opts->writable; + vblk_exp->vqs_started = true; config.capacity = cpu_to_le64(blk_getlength(exp->blk) >> VIRTIO_BLK_SECTOR_BITS); @@ -322,14 +368,20 @@ static int vduse_blk_exp_create(BlockExport *exp, BlockExportOptions *opts, vduse_dev_setup_queue(vblk_exp->dev, i, queue_size); } - aio_set_fd_handler(exp->ctx, vduse_dev_get_fd(vblk_exp->dev), true, + aio_set_fd_handler(exp->ctx, vduse_dev_get_fd(vblk_exp->dev), false, on_vduse_dev_kick, NULL, NULL, NULL, vblk_exp->dev); blk_add_aio_context_notifier(exp->blk, blk_aio_attached, blk_aio_detach, vblk_exp); - blk_set_dev_ops(exp->blk, &vduse_block_ops, exp); + /* + * We handle draining ourselves using an in-flight counter and by disabling + * virtqueue fd handlers. Do not queue BlockBackend requests, they need to + * complete so the in-flight counter reaches zero. + */ + blk_set_disable_request_queuing(exp->blk, true); + return 0; err: vduse_dev_destroy(vblk_exp->dev); @@ -344,6 +396,9 @@ static void vduse_blk_exp_delete(BlockExport *exp) VduseBlkExport *vblk_exp = container_of(exp, VduseBlkExport, export); int ret; + assert(qatomic_read(&vblk_exp->inflight) == 0); + + vduse_blk_detach_ctx(vblk_exp); blk_remove_aio_context_notifier(exp->blk, blk_aio_attached, blk_aio_detach, vblk_exp); ret = vduse_dev_destroy(vblk_exp->dev); @@ -354,13 +409,12 @@ static void vduse_blk_exp_delete(BlockExport *exp) g_free(vblk_exp->handler.serial); } +/* Called with exp->ctx acquired */ static void vduse_blk_exp_request_shutdown(BlockExport *exp) { VduseBlkExport *vblk_exp = container_of(exp, VduseBlkExport, export); - aio_context_acquire(vblk_exp->export.ctx); - vduse_blk_detach_ctx(vblk_exp); - aio_context_acquire(vblk_exp->export.ctx); + vduse_blk_stop_virtqueues(vblk_exp); } const BlockExportDriver blk_exp_vduse_blk = { From patchwork Thu May 4 19:53:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 13231749 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 55A5EC77B78 for ; Thu, 4 May 2023 20:00:32 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.530116.825511 (Exim 4.92) (envelope-from ) id 1puf7d-0005tz-5D; Thu, 04 May 2023 20:00:13 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 530116.825511; Thu, 04 May 2023 20:00:13 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf7c-0005so-V1; Thu, 04 May 2023 20:00:12 +0000 Received: by outflank-mailman (input) for mailman id 530116; Thu, 04 May 2023 20:00:10 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf1t-0003iB-Vn for xen-devel@lists.xenproject.org; Thu, 04 May 2023 19:54:17 +0000 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 7358d671-eab5-11ed-b226-6b7b168915f2; Thu, 04 May 2023 21:54:17 +0200 (CEST) Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-94-EVERd-b1O6iV68LQZZKd_A-1; Thu, 04 May 2023 15:54:10 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.rdu2.redhat.com [10.11.54.2]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id EC0B6A0F389; Thu, 4 May 2023 19:54:08 +0000 (UTC) Received: from localhost (unknown [10.39.192.57]) by smtp.corp.redhat.com (Postfix) with ESMTP id 51B294020960; Thu, 4 May 2023 19:54:08 +0000 (UTC) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 7358d671-eab5-11ed-b226-6b7b168915f2 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1683230056; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=bn7vYKIN4BAATa1eS0drL+2+35bJodnZI5fsBJiYTKs=; b=E6pRBqtnxp0TP87WMNL+URfi5WzVeWaz1lK3LF8Jf47/gjBQowXxde02YVjVwNLuWbYNB6 /rdqsEIHgki4Ndsn5e4KruXtYhgcERq6rdpvSzIUwB4XwmDVj+6aHHHTb3nU8KQ4D9QD4j SzHpPG6CzzghWV6mKeKo/CVRplBXH5g= X-MC-Unique: EVERd-b1O6iV68LQZZKd_A-1 From: Stefan Hajnoczi To: qemu-devel@nongnu.org Cc: Ronnie Sahlberg , Aarushi Mehta , qemu-block@nongnu.org, Paul Durrant , Anthony Perard , Peter Lieven , Stefan Weil , Xie Yongji , Kevin Wolf , Paolo Bonzini , "Michael S. Tsirkin" , Leonardo Bras , Peter Xu , Hanna Reitz , Stefano Stabellini , Richard Henderson , David Woodhouse , Coiby Xu , Eduardo Habkost , Stefano Garzarella , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , Stefan Hajnoczi , Julia Suvorova , xen-devel@lists.xenproject.org, eesposit@redhat.com, Juan Quintela , "Richard W.M. Jones" , Fam Zheng , Marcel Apfelbaum Subject: [PATCH v5 15/21] block/export: don't require AioContext lock around blk_exp_ref/unref() Date: Thu, 4 May 2023 15:53:21 -0400 Message-Id: <20230504195327.695107-16-stefanha@redhat.com> In-Reply-To: <20230504195327.695107-1-stefanha@redhat.com> References: <20230504195327.695107-1-stefanha@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.2 The FUSE export calls blk_exp_ref/unref() without the AioContext lock. Instead of fixing the FUSE export, adjust blk_exp_ref/unref() so they work without the AioContext lock. This way it's less error-prone. Suggested-by: Paolo Bonzini Signed-off-by: Stefan Hajnoczi --- include/block/export.h | 2 ++ block/export/export.c | 13 ++++++------- block/export/vduse-blk.c | 4 ---- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/include/block/export.h b/include/block/export.h index 7feb02e10d..f2fe0f8078 100644 --- a/include/block/export.h +++ b/include/block/export.h @@ -57,6 +57,8 @@ struct BlockExport { * Reference count for this block export. This includes strong references * both from the owner (qemu-nbd or the monitor) and clients connected to * the export. + * + * Use atomics to access this field. */ int refcount; diff --git a/block/export/export.c b/block/export/export.c index 62c7c22d45..ab007e9d31 100644 --- a/block/export/export.c +++ b/block/export/export.c @@ -202,11 +202,10 @@ fail: return NULL; } -/* Callers must hold exp->ctx lock */ void blk_exp_ref(BlockExport *exp) { - assert(exp->refcount > 0); - exp->refcount++; + assert(qatomic_read(&exp->refcount) > 0); + qatomic_inc(&exp->refcount); } /* Runs in the main thread */ @@ -229,11 +228,10 @@ static void blk_exp_delete_bh(void *opaque) aio_context_release(aio_context); } -/* Callers must hold exp->ctx lock */ void blk_exp_unref(BlockExport *exp) { - assert(exp->refcount > 0); - if (--exp->refcount == 0) { + assert(qatomic_read(&exp->refcount) > 0); + if (qatomic_fetch_dec(&exp->refcount) == 1) { /* Touch the block_exports list only in the main thread */ aio_bh_schedule_oneshot(qemu_get_aio_context(), blk_exp_delete_bh, exp); @@ -341,7 +339,8 @@ void qmp_block_export_del(const char *id, if (!has_mode) { mode = BLOCK_EXPORT_REMOVE_MODE_SAFE; } - if (mode == BLOCK_EXPORT_REMOVE_MODE_SAFE && exp->refcount > 1) { + if (mode == BLOCK_EXPORT_REMOVE_MODE_SAFE && + qatomic_read(&exp->refcount) > 1) { error_setg(errp, "export '%s' still in use", exp->id); error_append_hint(errp, "Use mode='hard' to force client " "disconnect\n"); diff --git a/block/export/vduse-blk.c b/block/export/vduse-blk.c index a25556fe04..e0455551f9 100644 --- a/block/export/vduse-blk.c +++ b/block/export/vduse-blk.c @@ -44,9 +44,7 @@ static void vduse_blk_inflight_inc(VduseBlkExport *vblk_exp) { if (qatomic_fetch_inc(&vblk_exp->inflight) == 0) { /* Prevent export from being deleted */ - aio_context_acquire(vblk_exp->export.ctx); blk_exp_ref(&vblk_exp->export); - aio_context_release(vblk_exp->export.ctx); } } @@ -57,9 +55,7 @@ static void vduse_blk_inflight_dec(VduseBlkExport *vblk_exp) aio_wait_kick(); /* Now the export can be deleted */ - aio_context_acquire(vblk_exp->export.ctx); blk_exp_unref(&vblk_exp->export); - aio_context_release(vblk_exp->export.ctx); } } From patchwork Thu May 4 19:53:22 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 13231746 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 015FCC7EE21 for ; Thu, 4 May 2023 19:59:46 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.530093.825446 (Exim 4.92) (envelope-from ) id 1puf6l-00029b-TE; Thu, 04 May 2023 19:59:19 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 530093.825446; Thu, 04 May 2023 19:59:19 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf6l-00029U-QM; Thu, 04 May 2023 19:59:19 +0000 Received: by outflank-mailman (input) for mailman id 530093; Thu, 04 May 2023 19:59:18 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf1v-0003xx-QK for xen-devel@lists.xenproject.org; Thu, 04 May 2023 19:54:19 +0000 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 732726f0-eab5-11ed-8611-37d641c3527e; Thu, 04 May 2023 21:54:16 +0200 (CEST) Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-311-pmj5n48DPI265atIoUKLhQ-1; Thu, 04 May 2023 15:54:12 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 78EBA855304; Thu, 4 May 2023 19:54:11 +0000 (UTC) Received: from localhost (unknown [10.39.192.57]) by smtp.corp.redhat.com (Postfix) with ESMTP id DB4002166B30; Thu, 4 May 2023 19:54:10 +0000 (UTC) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 732726f0-eab5-11ed-8611-37d641c3527e DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1683230055; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=pXsgzUQNPWG1ZQh/g83GoR8nnGiyShUYhUlRFMynpck=; b=LLvQInOb3cY5EaZPXCFCBQngtWgL2hlRshh00E2VEU/8EUi3VryPt+evBdNGoje4Ifbzeq ubrqBZEy6RlpJtvugbWI2NJTZUCJOhBfjzoB6YhQ2+yrQjZ8v0/c9254je/izmLXQvKx2D CqOWg14P8OWSNDy+XUKUU/BoZ+25+P4= X-MC-Unique: pmj5n48DPI265atIoUKLhQ-1 From: Stefan Hajnoczi To: qemu-devel@nongnu.org Cc: Ronnie Sahlberg , Aarushi Mehta , qemu-block@nongnu.org, Paul Durrant , Anthony Perard , Peter Lieven , Stefan Weil , Xie Yongji , Kevin Wolf , Paolo Bonzini , "Michael S. Tsirkin" , Leonardo Bras , Peter Xu , Hanna Reitz , Stefano Stabellini , Richard Henderson , David Woodhouse , Coiby Xu , Eduardo Habkost , Stefano Garzarella , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , Stefan Hajnoczi , Julia Suvorova , xen-devel@lists.xenproject.org, eesposit@redhat.com, Juan Quintela , "Richard W.M. Jones" , Fam Zheng , Marcel Apfelbaum Subject: [PATCH v5 16/21] block/fuse: do not set is_external=true on FUSE fd Date: Thu, 4 May 2023 15:53:22 -0400 Message-Id: <20230504195327.695107-17-stefanha@redhat.com> In-Reply-To: <20230504195327.695107-1-stefanha@redhat.com> References: <20230504195327.695107-1-stefanha@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 This is part of ongoing work to remove the aio_disable_external() API. Use BlockDevOps .drained_begin/end/poll() instead of aio_set_fd_handler(is_external=true). As a side-effect the FUSE export now follows AioContext changes like the other export types. Signed-off-by: Stefan Hajnoczi --- block/export/fuse.c | 56 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/block/export/fuse.c b/block/export/fuse.c index 06fa41079e..adf3236b5a 100644 --- a/block/export/fuse.c +++ b/block/export/fuse.c @@ -50,6 +50,7 @@ typedef struct FuseExport { struct fuse_session *fuse_session; struct fuse_buf fuse_buf; + unsigned int in_flight; /* atomic */ bool mounted, fd_handler_set_up; char *mountpoint; @@ -78,6 +79,42 @@ static void read_from_fuse_export(void *opaque); static bool is_regular_file(const char *path, Error **errp); +static void fuse_export_drained_begin(void *opaque) +{ + FuseExport *exp = opaque; + + aio_set_fd_handler(exp->common.ctx, + fuse_session_fd(exp->fuse_session), false, + NULL, NULL, NULL, NULL, NULL); + exp->fd_handler_set_up = false; +} + +static void fuse_export_drained_end(void *opaque) +{ + FuseExport *exp = opaque; + + /* Refresh AioContext in case it changed */ + exp->common.ctx = blk_get_aio_context(exp->common.blk); + + aio_set_fd_handler(exp->common.ctx, + fuse_session_fd(exp->fuse_session), false, + read_from_fuse_export, NULL, NULL, NULL, exp); + exp->fd_handler_set_up = true; +} + +static bool fuse_export_drained_poll(void *opaque) +{ + FuseExport *exp = opaque; + + return qatomic_read(&exp->in_flight) > 0; +} + +static const BlockDevOps fuse_export_blk_dev_ops = { + .drained_begin = fuse_export_drained_begin, + .drained_end = fuse_export_drained_end, + .drained_poll = fuse_export_drained_poll, +}; + static int fuse_export_create(BlockExport *blk_exp, BlockExportOptions *blk_exp_args, Error **errp) @@ -101,6 +138,15 @@ static int fuse_export_create(BlockExport *blk_exp, } } + blk_set_dev_ops(exp->common.blk, &fuse_export_blk_dev_ops, exp); + + /* + * We handle draining ourselves using an in-flight counter and by disabling + * the FUSE fd handler. Do not queue BlockBackend requests, they need to + * complete so the in-flight counter reaches zero. + */ + blk_set_disable_request_queuing(exp->common.blk, true); + init_exports_table(); /* @@ -224,7 +270,7 @@ static int setup_fuse_export(FuseExport *exp, const char *mountpoint, g_hash_table_insert(exports, g_strdup(mountpoint), NULL); aio_set_fd_handler(exp->common.ctx, - fuse_session_fd(exp->fuse_session), true, + fuse_session_fd(exp->fuse_session), false, read_from_fuse_export, NULL, NULL, NULL, exp); exp->fd_handler_set_up = true; @@ -246,6 +292,8 @@ static void read_from_fuse_export(void *opaque) blk_exp_ref(&exp->common); + qatomic_inc(&exp->in_flight); + do { ret = fuse_session_receive_buf(exp->fuse_session, &exp->fuse_buf); } while (ret == -EINTR); @@ -256,6 +304,10 @@ static void read_from_fuse_export(void *opaque) fuse_session_process_buf(exp->fuse_session, &exp->fuse_buf); out: + if (qatomic_fetch_dec(&exp->in_flight) == 1) { + aio_wait_kick(); /* wake AIO_WAIT_WHILE() */ + } + blk_exp_unref(&exp->common); } @@ -268,7 +320,7 @@ static void fuse_export_shutdown(BlockExport *blk_exp) if (exp->fd_handler_set_up) { aio_set_fd_handler(exp->common.ctx, - fuse_session_fd(exp->fuse_session), true, + fuse_session_fd(exp->fuse_session), false, NULL, NULL, NULL, NULL, NULL); exp->fd_handler_set_up = false; } From patchwork Thu May 4 19:53:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 13231748 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id AB4C4C77B78 for ; Thu, 4 May 2023 20:00:29 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.530110.825486 (Exim 4.92) (envelope-from ) id 1puf7W-0005Az-45; Thu, 04 May 2023 20:00:06 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 530110.825486; Thu, 04 May 2023 20:00:06 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf7V-0005As-VA; Thu, 04 May 2023 20:00:05 +0000 Received: by outflank-mailman (input) for mailman id 530110; Thu, 04 May 2023 20:00:05 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf1y-0003xx-0Y for xen-devel@lists.xenproject.org; Thu, 04 May 2023 19:54:22 +0000 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 752ae21e-eab5-11ed-8611-37d641c3527e; Thu, 04 May 2023 21:54:20 +0200 (CEST) Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-635-rnzRckGWN_uYxyN68Qx0aw-1; Thu, 04 May 2023 15:54:15 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id A63E5101A531; Thu, 4 May 2023 19:54:13 +0000 (UTC) Received: from localhost (unknown [10.39.192.57]) by smtp.corp.redhat.com (Postfix) with ESMTP id E92B763F3E; Thu, 4 May 2023 19:54:12 +0000 (UTC) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 752ae21e-eab5-11ed-8611-37d641c3527e DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1683230059; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=94EbW6UEPYMLwV9zB8HOwndWfCZlP2kutpuX+h7WMqo=; b=TaCAoYoEpnhHFw4ZKWwTsG7GbZ0YvaDn5NTWcZ/jZDa3c4KlIcULOT36dZiExKMMTVnE7o UBao6Axld3t7VTAfWW3isW+Ye8ny5/OtoWfP+3Z2s7drTiyrp8aidxwNY9jwqu3QjltNcY p8HKKe6OkyZ4msncWm5i5djPhMndmko= X-MC-Unique: rnzRckGWN_uYxyN68Qx0aw-1 From: Stefan Hajnoczi To: qemu-devel@nongnu.org Cc: Ronnie Sahlberg , Aarushi Mehta , qemu-block@nongnu.org, Paul Durrant , Anthony Perard , Peter Lieven , Stefan Weil , Xie Yongji , Kevin Wolf , Paolo Bonzini , "Michael S. Tsirkin" , Leonardo Bras , Peter Xu , Hanna Reitz , Stefano Stabellini , Richard Henderson , David Woodhouse , Coiby Xu , Eduardo Habkost , Stefano Garzarella , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , Stefan Hajnoczi , Julia Suvorova , xen-devel@lists.xenproject.org, eesposit@redhat.com, Juan Quintela , "Richard W.M. Jones" , Fam Zheng , Marcel Apfelbaum Subject: [PATCH v5 17/21] virtio: make it possible to detach host notifier from any thread Date: Thu, 4 May 2023 15:53:23 -0400 Message-Id: <20230504195327.695107-18-stefanha@redhat.com> In-Reply-To: <20230504195327.695107-1-stefanha@redhat.com> References: <20230504195327.695107-1-stefanha@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.5 virtio_queue_aio_detach_host_notifier() does two things: 1. It removes the fd handler from the event loop. 2. It processes the virtqueue one last time. The first step can be peformed by any thread and without taking the AioContext lock. The second step may need the AioContext lock (depending on the device implementation) and runs in the thread where request processing takes place. virtio-blk and virtio-scsi therefore call virtio_queue_aio_detach_host_notifier() from a BH that is scheduled in AioContext Scheduling a BH is undesirable for .drained_begin() functions. The next patch will introduce a .drained_begin() function that needs to call virtio_queue_aio_detach_host_notifier(). Move the virtqueue processing out to the callers of virtio_queue_aio_detach_host_notifier() so that the function can be called from any thread. This is in preparation for the next patch. Signed-off-by: Stefan Hajnoczi --- hw/block/dataplane/virtio-blk.c | 2 ++ hw/scsi/virtio-scsi-dataplane.c | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c index a6202997ee..27eafa6c92 100644 --- a/hw/block/dataplane/virtio-blk.c +++ b/hw/block/dataplane/virtio-blk.c @@ -287,8 +287,10 @@ static void virtio_blk_data_plane_stop_bh(void *opaque) for (i = 0; i < s->conf->num_queues; i++) { VirtQueue *vq = virtio_get_queue(s->vdev, i); + EventNotifier *host_notifier = virtio_queue_get_host_notifier(vq); virtio_queue_aio_detach_host_notifier(vq, s->ctx); + virtio_queue_host_notifier_read(host_notifier); } } diff --git a/hw/scsi/virtio-scsi-dataplane.c b/hw/scsi/virtio-scsi-dataplane.c index 20bb91766e..81643445ed 100644 --- a/hw/scsi/virtio-scsi-dataplane.c +++ b/hw/scsi/virtio-scsi-dataplane.c @@ -71,12 +71,21 @@ static void virtio_scsi_dataplane_stop_bh(void *opaque) { VirtIOSCSI *s = opaque; VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s); + EventNotifier *host_notifier; int i; virtio_queue_aio_detach_host_notifier(vs->ctrl_vq, s->ctx); + host_notifier = virtio_queue_get_host_notifier(vs->ctrl_vq); + virtio_queue_host_notifier_read(host_notifier); + virtio_queue_aio_detach_host_notifier(vs->event_vq, s->ctx); + host_notifier = virtio_queue_get_host_notifier(vs->event_vq); + virtio_queue_host_notifier_read(host_notifier); + for (i = 0; i < vs->conf.num_queues; i++) { virtio_queue_aio_detach_host_notifier(vs->cmd_vqs[i], s->ctx); + host_notifier = virtio_queue_get_host_notifier(vs->cmd_vqs[i]); + virtio_queue_host_notifier_read(host_notifier); } } From patchwork Thu May 4 19:53:24 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 13231745 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C314CC77B78 for ; Thu, 4 May 2023 19:59:46 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.530096.825476 (Exim 4.92) (envelope-from ) id 1puf6t-0002yF-Ot; Thu, 04 May 2023 19:59:27 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 530096.825476; Thu, 04 May 2023 19:59:27 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf6t-0002xx-L0; Thu, 04 May 2023 19:59:27 +0000 Received: by outflank-mailman (input) for mailman id 530096; Thu, 04 May 2023 19:59:26 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf1y-0003iB-Ae for xen-devel@lists.xenproject.org; Thu, 04 May 2023 19:54:22 +0000 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 75f0b3fa-eab5-11ed-b226-6b7b168915f2; Thu, 04 May 2023 21:54:21 +0200 (CEST) Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-37-JLyMG8AyOQ6Ztjf5K0NY6Q-1; Thu, 04 May 2023 15:54:17 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 24421101A531; Thu, 4 May 2023 19:54:16 +0000 (UTC) Received: from localhost (unknown [10.39.192.57]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5E4CA1121331; Thu, 4 May 2023 19:54:15 +0000 (UTC) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 75f0b3fa-eab5-11ed-b226-6b7b168915f2 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1683230060; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ruJgs45mwGYUnVoP6uIPKYhuhXIe1j+KFcN94nSbefs=; b=aMVbuSe9iyN4M9RlotmvoTWgdJEdpEiOCXkrmbFb+DGJW6eM/bzDVG909kUXfuQaUTQ6WC 03xS/T+8udfRyeJIZw0FoxBY75ORE0KmB4lH0wD7c3puVR7tnUovNmAuoQzhecjPa2wAsk McLai88FozIa1WR7r3xXEvFojNk/bck= X-MC-Unique: JLyMG8AyOQ6Ztjf5K0NY6Q-1 From: Stefan Hajnoczi To: qemu-devel@nongnu.org Cc: Ronnie Sahlberg , Aarushi Mehta , qemu-block@nongnu.org, Paul Durrant , Anthony Perard , Peter Lieven , Stefan Weil , Xie Yongji , Kevin Wolf , Paolo Bonzini , "Michael S. Tsirkin" , Leonardo Bras , Peter Xu , Hanna Reitz , Stefano Stabellini , Richard Henderson , David Woodhouse , Coiby Xu , Eduardo Habkost , Stefano Garzarella , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , Stefan Hajnoczi , Julia Suvorova , xen-devel@lists.xenproject.org, eesposit@redhat.com, Juan Quintela , "Richard W.M. Jones" , Fam Zheng , Marcel Apfelbaum Subject: [PATCH v5 18/21] virtio-blk: implement BlockDevOps->drained_begin() Date: Thu, 4 May 2023 15:53:24 -0400 Message-Id: <20230504195327.695107-19-stefanha@redhat.com> In-Reply-To: <20230504195327.695107-1-stefanha@redhat.com> References: <20230504195327.695107-1-stefanha@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.3 Detach ioeventfds during drained sections to stop I/O submission from the guest. virtio-blk is no longer reliant on aio_disable_external() after this patch. This will allow us to remove the aio_disable_external() API once all other code that relies on it is converted. Take extra care to avoid attaching/detaching ioeventfds if the data plane is started/stopped during a drained section. This should be rare, but maybe the mirror block job can trigger it. Signed-off-by: Stefan Hajnoczi --- hw/block/dataplane/virtio-blk.c | 17 +++++++++------ hw/block/virtio-blk.c | 38 ++++++++++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 7 deletions(-) diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c index 27eafa6c92..c0d2663abc 100644 --- a/hw/block/dataplane/virtio-blk.c +++ b/hw/block/dataplane/virtio-blk.c @@ -246,13 +246,15 @@ int virtio_blk_data_plane_start(VirtIODevice *vdev) } /* Get this show started by hooking up our callbacks */ - aio_context_acquire(s->ctx); - for (i = 0; i < nvqs; i++) { - VirtQueue *vq = virtio_get_queue(s->vdev, i); + if (!blk_in_drain(s->conf->conf.blk)) { + aio_context_acquire(s->ctx); + for (i = 0; i < nvqs; i++) { + VirtQueue *vq = virtio_get_queue(s->vdev, i); - virtio_queue_aio_attach_host_notifier(vq, s->ctx); + virtio_queue_aio_attach_host_notifier(vq, s->ctx); + } + aio_context_release(s->ctx); } - aio_context_release(s->ctx); return 0; fail_aio_context: @@ -318,7 +320,10 @@ void virtio_blk_data_plane_stop(VirtIODevice *vdev) trace_virtio_blk_data_plane_stop(s); aio_context_acquire(s->ctx); - aio_wait_bh_oneshot(s->ctx, virtio_blk_data_plane_stop_bh, s); + + if (!blk_in_drain(s->conf->conf.blk)) { + aio_wait_bh_oneshot(s->ctx, virtio_blk_data_plane_stop_bh, s); + } /* Wait for virtio_blk_dma_restart_bh() and in flight I/O to complete */ blk_drain(s->conf->conf.blk); diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index cefca93b31..d8dedc575c 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -1109,8 +1109,44 @@ static void virtio_blk_resize(void *opaque) aio_bh_schedule_oneshot(qemu_get_aio_context(), virtio_resize_cb, vdev); } +/* Suspend virtqueue ioeventfd processing during drain */ +static void virtio_blk_drained_begin(void *opaque) +{ + VirtIOBlock *s = opaque; + VirtIODevice *vdev = VIRTIO_DEVICE(opaque); + AioContext *ctx = blk_get_aio_context(s->conf.conf.blk); + + if (!s->dataplane || !s->dataplane_started) { + return; + } + + for (uint16_t i = 0; i < s->conf.num_queues; i++) { + VirtQueue *vq = virtio_get_queue(vdev, i); + virtio_queue_aio_detach_host_notifier(vq, ctx); + } +} + +/* Resume virtqueue ioeventfd processing after drain */ +static void virtio_blk_drained_end(void *opaque) +{ + VirtIOBlock *s = opaque; + VirtIODevice *vdev = VIRTIO_DEVICE(opaque); + AioContext *ctx = blk_get_aio_context(s->conf.conf.blk); + + if (!s->dataplane || !s->dataplane_started) { + return; + } + + for (uint16_t i = 0; i < s->conf.num_queues; i++) { + VirtQueue *vq = virtio_get_queue(vdev, i); + virtio_queue_aio_attach_host_notifier(vq, ctx); + } +} + static const BlockDevOps virtio_block_ops = { - .resize_cb = virtio_blk_resize, + .resize_cb = virtio_blk_resize, + .drained_begin = virtio_blk_drained_begin, + .drained_end = virtio_blk_drained_end, }; static void virtio_blk_device_realize(DeviceState *dev, Error **errp) From patchwork Thu May 4 19:53:25 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 13231751 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 18AB5C7EE21 for ; Thu, 4 May 2023 20:00:38 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.530115.825506 (Exim 4.92) (envelope-from ) id 1puf7c-0005q2-QB; Thu, 04 May 2023 20:00:12 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 530115.825506; Thu, 04 May 2023 20:00:12 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf7c-0005pv-Mx; Thu, 04 May 2023 20:00:12 +0000 Received: by outflank-mailman (input) for mailman id 530115; Thu, 04 May 2023 20:00:10 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf21-0003xx-RY for xen-devel@lists.xenproject.org; Thu, 04 May 2023 19:54:25 +0000 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 77395080-eab5-11ed-8611-37d641c3527e; Thu, 04 May 2023 21:54:23 +0200 (CEST) Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-86-xBjZ8_DjNQ-jsqK3HPfxEg-1; Thu, 04 May 2023 15:54:20 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.rdu2.redhat.com [10.11.54.2]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id A1B9C886063; Thu, 4 May 2023 19:54:19 +0000 (UTC) Received: from localhost (unknown [10.39.192.57]) by smtp.corp.redhat.com (Postfix) with ESMTP id 297BC4020960; Thu, 4 May 2023 19:54:17 +0000 (UTC) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 77395080-eab5-11ed-8611-37d641c3527e DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1683230062; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ckhE010jxhkqU+qGTRwp1CzCNoAx+VwzdwbJyrduiJo=; b=Rb7XL2IIisdNrWUxDLBtrFscNuTsQ6sFpEbq52XDXOMQMPFyEC1acEeFZT27SJrqtnY2G7 iiBND0pYGclRy4EwyoQaKk16KGQKhG+pVveJJVFjkZmo/9hZD+JqClrrjgc7X5nluvEHL7 ZYTlIsK7dgI5cZvZNnP9xXW9pBTNLKY= X-MC-Unique: xBjZ8_DjNQ-jsqK3HPfxEg-1 From: Stefan Hajnoczi To: qemu-devel@nongnu.org Cc: Ronnie Sahlberg , Aarushi Mehta , qemu-block@nongnu.org, Paul Durrant , Anthony Perard , Peter Lieven , Stefan Weil , Xie Yongji , Kevin Wolf , Paolo Bonzini , "Michael S. Tsirkin" , Leonardo Bras , Peter Xu , Hanna Reitz , Stefano Stabellini , Richard Henderson , David Woodhouse , Coiby Xu , Eduardo Habkost , Stefano Garzarella , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , Stefan Hajnoczi , Julia Suvorova , xen-devel@lists.xenproject.org, eesposit@redhat.com, Juan Quintela , "Richard W.M. Jones" , Fam Zheng , Marcel Apfelbaum Subject: [PATCH v5 19/21] virtio-scsi: implement BlockDevOps->drained_begin() Date: Thu, 4 May 2023 15:53:25 -0400 Message-Id: <20230504195327.695107-20-stefanha@redhat.com> In-Reply-To: <20230504195327.695107-1-stefanha@redhat.com> References: <20230504195327.695107-1-stefanha@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.2 The virtio-scsi Host Bus Adapter provides access to devices on a SCSI bus. Those SCSI devices typically have a BlockBackend. When the BlockBackend enters a drained section, the SCSI device must temporarily stop submitting new I/O requests. Implement this behavior by temporarily stopping virtio-scsi virtqueue processing when one of the SCSI devices enters a drained section. The new scsi_device_drained_begin() API allows scsi-disk to message the virtio-scsi HBA. scsi_device_drained_begin() uses a drain counter so that multiple SCSI devices can have overlapping drained sections. The HBA only sees one pair of .drained_begin/end() calls. After this commit, virtio-scsi no longer depends on hw/virtio's ioeventfd aio_set_event_notifier(is_external=true). This commit is a step towards removing the aio_disable_external() API. Signed-off-by: Stefan Hajnoczi --- include/hw/scsi/scsi.h | 14 ++++++++++++ hw/scsi/scsi-bus.c | 40 +++++++++++++++++++++++++++++++++ hw/scsi/scsi-disk.c | 27 +++++++++++++++++----- hw/scsi/virtio-scsi-dataplane.c | 22 ++++++++++-------- hw/scsi/virtio-scsi.c | 38 +++++++++++++++++++++++++++++++ hw/scsi/trace-events | 2 ++ 6 files changed, 129 insertions(+), 14 deletions(-) diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h index 6f23a7a73e..e2bb1a2fbf 100644 --- a/include/hw/scsi/scsi.h +++ b/include/hw/scsi/scsi.h @@ -133,6 +133,16 @@ struct SCSIBusInfo { void (*save_request)(QEMUFile *f, SCSIRequest *req); void *(*load_request)(QEMUFile *f, SCSIRequest *req); void (*free_request)(SCSIBus *bus, void *priv); + + /* + * Temporarily stop submitting new requests between drained_begin() and + * drained_end(). Called from the main loop thread with the BQL held. + * + * Implement these callbacks if request processing is triggered by a file + * descriptor like an EventNotifier. Otherwise set them to NULL. + */ + void (*drained_begin)(SCSIBus *bus); + void (*drained_end)(SCSIBus *bus); }; #define TYPE_SCSI_BUS "SCSI" @@ -144,6 +154,8 @@ struct SCSIBus { SCSISense unit_attention; const SCSIBusInfo *info; + + int drain_count; /* protected by BQL */ }; /** @@ -213,6 +225,8 @@ void scsi_req_cancel_complete(SCSIRequest *req); void scsi_req_cancel(SCSIRequest *req); void scsi_req_cancel_async(SCSIRequest *req, Notifier *notifier); void scsi_req_retry(SCSIRequest *req); +void scsi_device_drained_begin(SCSIDevice *sdev); +void scsi_device_drained_end(SCSIDevice *sdev); void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense); void scsi_device_set_ua(SCSIDevice *sdev, SCSISense sense); void scsi_device_report_change(SCSIDevice *dev, SCSISense sense); diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c index 64013c8a24..f80f4cb4fc 100644 --- a/hw/scsi/scsi-bus.c +++ b/hw/scsi/scsi-bus.c @@ -1669,6 +1669,46 @@ void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense) scsi_device_set_ua(sdev, sense); } +void scsi_device_drained_begin(SCSIDevice *sdev) +{ + SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, sdev->qdev.parent_bus); + if (!bus) { + return; + } + + assert(qemu_get_current_aio_context() == qemu_get_aio_context()); + assert(bus->drain_count < INT_MAX); + + /* + * Multiple BlockBackends can be on a SCSIBus and each may begin/end + * draining at any time. Keep a counter so HBAs only see begin/end once. + */ + if (bus->drain_count++ == 0) { + trace_scsi_bus_drained_begin(bus, sdev); + if (bus->info->drained_begin) { + bus->info->drained_begin(bus); + } + } +} + +void scsi_device_drained_end(SCSIDevice *sdev) +{ + SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, sdev->qdev.parent_bus); + if (!bus) { + return; + } + + assert(qemu_get_current_aio_context() == qemu_get_aio_context()); + assert(bus->drain_count > 0); + + if (bus->drain_count-- == 1) { + trace_scsi_bus_drained_end(bus, sdev); + if (bus->info->drained_end) { + bus->info->drained_end(bus); + } + } +} + static char *scsibus_get_dev_path(DeviceState *dev) { SCSIDevice *d = SCSI_DEVICE(dev); diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c index 97c9b1c8cd..e0d79c7966 100644 --- a/hw/scsi/scsi-disk.c +++ b/hw/scsi/scsi-disk.c @@ -2360,6 +2360,20 @@ static void scsi_disk_reset(DeviceState *dev) s->qdev.scsi_version = s->qdev.default_scsi_version; } +static void scsi_disk_drained_begin(void *opaque) +{ + SCSIDiskState *s = opaque; + + scsi_device_drained_begin(&s->qdev); +} + +static void scsi_disk_drained_end(void *opaque) +{ + SCSIDiskState *s = opaque; + + scsi_device_drained_end(&s->qdev); +} + static void scsi_disk_resize_cb(void *opaque) { SCSIDiskState *s = opaque; @@ -2414,16 +2428,19 @@ static bool scsi_cd_is_medium_locked(void *opaque) } static const BlockDevOps scsi_disk_removable_block_ops = { - .change_media_cb = scsi_cd_change_media_cb, + .change_media_cb = scsi_cd_change_media_cb, + .drained_begin = scsi_disk_drained_begin, + .drained_end = scsi_disk_drained_end, .eject_request_cb = scsi_cd_eject_request_cb, - .is_tray_open = scsi_cd_is_tray_open, .is_medium_locked = scsi_cd_is_medium_locked, - - .resize_cb = scsi_disk_resize_cb, + .is_tray_open = scsi_cd_is_tray_open, + .resize_cb = scsi_disk_resize_cb, }; static const BlockDevOps scsi_disk_block_ops = { - .resize_cb = scsi_disk_resize_cb, + .drained_begin = scsi_disk_drained_begin, + .drained_end = scsi_disk_drained_end, + .resize_cb = scsi_disk_resize_cb, }; static void scsi_disk_unit_attention_reported(SCSIDevice *dev) diff --git a/hw/scsi/virtio-scsi-dataplane.c b/hw/scsi/virtio-scsi-dataplane.c index 81643445ed..1060038e13 100644 --- a/hw/scsi/virtio-scsi-dataplane.c +++ b/hw/scsi/virtio-scsi-dataplane.c @@ -153,14 +153,16 @@ int virtio_scsi_dataplane_start(VirtIODevice *vdev) s->dataplane_starting = false; s->dataplane_started = true; - aio_context_acquire(s->ctx); - virtio_queue_aio_attach_host_notifier(vs->ctrl_vq, s->ctx); - virtio_queue_aio_attach_host_notifier_no_poll(vs->event_vq, s->ctx); + if (s->bus.drain_count == 0) { + aio_context_acquire(s->ctx); + virtio_queue_aio_attach_host_notifier(vs->ctrl_vq, s->ctx); + virtio_queue_aio_attach_host_notifier_no_poll(vs->event_vq, s->ctx); - for (i = 0; i < vs->conf.num_queues; i++) { - virtio_queue_aio_attach_host_notifier(vs->cmd_vqs[i], s->ctx); + for (i = 0; i < vs->conf.num_queues; i++) { + virtio_queue_aio_attach_host_notifier(vs->cmd_vqs[i], s->ctx); + } + aio_context_release(s->ctx); } - aio_context_release(s->ctx); return 0; fail_host_notifiers: @@ -206,9 +208,11 @@ void virtio_scsi_dataplane_stop(VirtIODevice *vdev) } s->dataplane_stopping = true; - aio_context_acquire(s->ctx); - aio_wait_bh_oneshot(s->ctx, virtio_scsi_dataplane_stop_bh, s); - aio_context_release(s->ctx); + if (s->bus.drain_count == 0) { + aio_context_acquire(s->ctx); + aio_wait_bh_oneshot(s->ctx, virtio_scsi_dataplane_stop_bh, s); + aio_context_release(s->ctx); + } blk_drain_all(); /* ensure there are no in-flight requests */ diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index c1a7ea9ae2..4a8849cc7e 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -1117,6 +1117,42 @@ static void virtio_scsi_hotunplug(HotplugHandler *hotplug_dev, DeviceState *dev, } } +/* Suspend virtqueue ioeventfd processing during drain */ +static void virtio_scsi_drained_begin(SCSIBus *bus) +{ + VirtIOSCSI *s = container_of(bus, VirtIOSCSI, bus); + VirtIODevice *vdev = VIRTIO_DEVICE(s); + uint32_t total_queues = VIRTIO_SCSI_VQ_NUM_FIXED + + s->parent_obj.conf.num_queues; + + if (!s->dataplane_started) { + return; + } + + for (uint32_t i = 0; i < total_queues; i++) { + VirtQueue *vq = virtio_get_queue(vdev, i); + virtio_queue_aio_detach_host_notifier(vq, s->ctx); + } +} + +/* Resume virtqueue ioeventfd processing after drain */ +static void virtio_scsi_drained_end(SCSIBus *bus) +{ + VirtIOSCSI *s = container_of(bus, VirtIOSCSI, bus); + VirtIODevice *vdev = VIRTIO_DEVICE(s); + uint32_t total_queues = VIRTIO_SCSI_VQ_NUM_FIXED + + s->parent_obj.conf.num_queues; + + if (!s->dataplane_started) { + return; + } + + for (uint32_t i = 0; i < total_queues; i++) { + VirtQueue *vq = virtio_get_queue(vdev, i); + virtio_queue_aio_attach_host_notifier(vq, s->ctx); + } +} + static struct SCSIBusInfo virtio_scsi_scsi_info = { .tcq = true, .max_channel = VIRTIO_SCSI_MAX_CHANNEL, @@ -1131,6 +1167,8 @@ static struct SCSIBusInfo virtio_scsi_scsi_info = { .get_sg_list = virtio_scsi_get_sg_list, .save_request = virtio_scsi_save_request, .load_request = virtio_scsi_load_request, + .drained_begin = virtio_scsi_drained_begin, + .drained_end = virtio_scsi_drained_end, }; void virtio_scsi_common_realize(DeviceState *dev, diff --git a/hw/scsi/trace-events b/hw/scsi/trace-events index ab238293f0..bdd4e2c7c7 100644 --- a/hw/scsi/trace-events +++ b/hw/scsi/trace-events @@ -6,6 +6,8 @@ scsi_req_cancel(int target, int lun, int tag) "target %d lun %d tag %d" scsi_req_data(int target, int lun, int tag, int len) "target %d lun %d tag %d len %d" scsi_req_data_canceled(int target, int lun, int tag, int len) "target %d lun %d tag %d len %d" scsi_req_dequeue(int target, int lun, int tag) "target %d lun %d tag %d" +scsi_bus_drained_begin(void *bus, void *sdev) "bus %p sdev %p" +scsi_bus_drained_end(void *bus, void *sdev) "bus %p sdev %p" scsi_req_continue(int target, int lun, int tag) "target %d lun %d tag %d" scsi_req_continue_canceled(int target, int lun, int tag) "target %d lun %d tag %d" scsi_req_parsed(int target, int lun, int tag, int cmd, int mode, int xfer) "target %d lun %d tag %d command %d dir %d length %d" From patchwork Thu May 4 19:53:26 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 13231744 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 00144C7EE25 for ; Thu, 4 May 2023 19:59:41 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.530094.825455 (Exim 4.92) (envelope-from ) id 1puf6o-0002Ox-4N; Thu, 04 May 2023 19:59:22 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 530094.825455; Thu, 04 May 2023 19:59:22 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf6o-0002Oq-1a; Thu, 04 May 2023 19:59:22 +0000 Received: by outflank-mailman (input) for mailman id 530094; Thu, 04 May 2023 19:59:21 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf28-0003xx-K8 for xen-devel@lists.xenproject.org; Thu, 04 May 2023 19:54:32 +0000 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 7b8f1ab9-eab5-11ed-8611-37d641c3527e; Thu, 04 May 2023 21:54:31 +0200 (CEST) Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-595-i1TCEUOyPMCxwUb6LaaevA-1; Thu, 04 May 2023 15:54:24 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id A91B5811E7E; Thu, 4 May 2023 19:54:23 +0000 (UTC) Received: from localhost (unknown [10.39.192.57]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0E16B2166B31; Thu, 4 May 2023 19:54:21 +0000 (UTC) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 7b8f1ab9-eab5-11ed-8611-37d641c3527e DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1683230069; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=peUabVxpb/f9SoCESFgzNkXObwSbZ6ll4imnzO2kIyY=; b=XoxQ/jxHYPKvkrOMDt7ssACzd/kVn1YwMjKNc5bk+7ES57V+Hchp9ORuWVUdH7ZbuIL7My 4ifEBGnlRAzo5DaMTj/T0Ze2lIe+yTFodtd+WYzg76uEg7TuJiPTfQJFRj69Zx567QsavY Zwc2tIB1tAnRDW/UOkGVdVHaJJ+/wSs= X-MC-Unique: i1TCEUOyPMCxwUb6LaaevA-1 From: Stefan Hajnoczi To: qemu-devel@nongnu.org Cc: Ronnie Sahlberg , Aarushi Mehta , qemu-block@nongnu.org, Paul Durrant , Anthony Perard , Peter Lieven , Stefan Weil , Xie Yongji , Kevin Wolf , Paolo Bonzini , "Michael S. Tsirkin" , Leonardo Bras , Peter Xu , Hanna Reitz , Stefano Stabellini , Richard Henderson , David Woodhouse , Coiby Xu , Eduardo Habkost , Stefano Garzarella , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , Stefan Hajnoczi , Julia Suvorova , xen-devel@lists.xenproject.org, eesposit@redhat.com, Juan Quintela , "Richard W.M. Jones" , Fam Zheng , Marcel Apfelbaum Subject: [PATCH v5 20/21] virtio: do not set is_external=true on host notifiers Date: Thu, 4 May 2023 15:53:26 -0400 Message-Id: <20230504195327.695107-21-stefanha@redhat.com> In-Reply-To: <20230504195327.695107-1-stefanha@redhat.com> References: <20230504195327.695107-1-stefanha@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 Host notifiers can now use is_external=false since virtio-blk and virtio-scsi no longer rely on is_external=true for drained sections. Signed-off-by: Stefan Hajnoczi --- hw/virtio/virtio.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 272d930721..9cdad7e550 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -3491,7 +3491,7 @@ static void virtio_queue_host_notifier_aio_poll_end(EventNotifier *n) void virtio_queue_aio_attach_host_notifier(VirtQueue *vq, AioContext *ctx) { - aio_set_event_notifier(ctx, &vq->host_notifier, true, + aio_set_event_notifier(ctx, &vq->host_notifier, false, virtio_queue_host_notifier_read, virtio_queue_host_notifier_aio_poll, virtio_queue_host_notifier_aio_poll_ready); @@ -3508,14 +3508,14 @@ void virtio_queue_aio_attach_host_notifier(VirtQueue *vq, AioContext *ctx) */ void virtio_queue_aio_attach_host_notifier_no_poll(VirtQueue *vq, AioContext *ctx) { - aio_set_event_notifier(ctx, &vq->host_notifier, true, + aio_set_event_notifier(ctx, &vq->host_notifier, false, virtio_queue_host_notifier_read, NULL, NULL); } void virtio_queue_aio_detach_host_notifier(VirtQueue *vq, AioContext *ctx) { - aio_set_event_notifier(ctx, &vq->host_notifier, true, NULL, NULL, NULL); + aio_set_event_notifier(ctx, &vq->host_notifier, false, NULL, NULL, NULL); /* Test and clear notifier before after disabling event, * in case poll callback didn't have time to run. */ virtio_queue_host_notifier_read(&vq->host_notifier); From patchwork Thu May 4 19:53:27 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 13231750 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 77D1DC7EE21 for ; Thu, 4 May 2023 20:00:30 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.530114.825496 (Exim 4.92) (envelope-from ) id 1puf7a-0005XZ-Bg; Thu, 04 May 2023 20:00:10 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 530114.825496; Thu, 04 May 2023 20:00:10 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf7a-0005XS-8d; Thu, 04 May 2023 20:00:10 +0000 Received: by outflank-mailman (input) for mailman id 530114; Thu, 04 May 2023 20:00:09 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1puf29-0003iB-86 for xen-devel@lists.xenproject.org; Thu, 04 May 2023 19:54:33 +0000 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 7ba0c59d-eab5-11ed-b226-6b7b168915f2; Thu, 04 May 2023 21:54:31 +0200 (CEST) Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-197-qnKcAnexPNuFuzoeplb57A-1; Thu, 04 May 2023 15:54:28 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 220D33C0F66C; Thu, 4 May 2023 19:54:27 +0000 (UTC) Received: from localhost (unknown [10.39.192.57]) by smtp.corp.redhat.com (Postfix) with ESMTP id D5CF340C2064; Thu, 4 May 2023 19:54:24 +0000 (UTC) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 7ba0c59d-eab5-11ed-b226-6b7b168915f2 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1683230070; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=DIrmY+4xB43BwQ7fJaY0YH2utqNnWk6FB76ZRZW5uOk=; b=C5Egk0MCk0umval0dUHvR5cPxYYrF5KxVdolEX2MgjQhngMh4DdlZwF3zlK5JPdGYN0g2Q YdTNiHBK5dJ8E9Q9U+2zZNsdV5j81w8B6ynuR1qkD+6IpPnLZxhps+zM87cULBMtoVCLLM QnX9ABO6t/ZOhz9LbyZJ+Z7KyRiUC0I= X-MC-Unique: qnKcAnexPNuFuzoeplb57A-1 From: Stefan Hajnoczi To: qemu-devel@nongnu.org Cc: Ronnie Sahlberg , Aarushi Mehta , qemu-block@nongnu.org, Paul Durrant , Anthony Perard , Peter Lieven , Stefan Weil , Xie Yongji , Kevin Wolf , Paolo Bonzini , "Michael S. Tsirkin" , Leonardo Bras , Peter Xu , Hanna Reitz , Stefano Stabellini , Richard Henderson , David Woodhouse , Coiby Xu , Eduardo Habkost , Stefano Garzarella , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , Stefan Hajnoczi , Julia Suvorova , xen-devel@lists.xenproject.org, eesposit@redhat.com, Juan Quintela , "Richard W.M. Jones" , Fam Zheng , Marcel Apfelbaum Subject: [PATCH v5 21/21] aio: remove aio_disable_external() API Date: Thu, 4 May 2023 15:53:27 -0400 Message-Id: <20230504195327.695107-22-stefanha@redhat.com> In-Reply-To: <20230504195327.695107-1-stefanha@redhat.com> References: <20230504195327.695107-1-stefanha@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.1 All callers now pass is_external=false to aio_set_fd_handler() and aio_set_event_notifier(). The aio_disable_external() API that temporarily disables fd handlers that were registered is_external=true is therefore dead code. Remove aio_disable_external(), aio_enable_external(), and the is_external arguments to aio_set_fd_handler() and aio_set_event_notifier(). The entire test-fdmon-epoll test is removed because its sole purpose was testing aio_disable_external(). Parts of this patch were generated using the following coccinelle (https://coccinelle.lip6.fr/) semantic patch: @@ expression ctx, fd, is_external, io_read, io_write, io_poll, io_poll_ready, opaque; @@ - aio_set_fd_handler(ctx, fd, is_external, io_read, io_write, io_poll, io_poll_ready, opaque) + aio_set_fd_handler(ctx, fd, io_read, io_write, io_poll, io_poll_ready, opaque) @@ expression ctx, notifier, is_external, io_read, io_poll, io_poll_ready; @@ - aio_set_event_notifier(ctx, notifier, is_external, io_read, io_poll, io_poll_ready) + aio_set_event_notifier(ctx, notifier, io_read, io_poll, io_poll_ready) Reviewed-by: Juan Quintela Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Stefan Hajnoczi --- include/block/aio.h | 57 --------------------------- util/aio-posix.h | 1 - block.c | 7 ---- block/blkio.c | 15 +++---- block/curl.c | 10 ++--- block/export/fuse.c | 8 ++-- block/export/vduse-blk.c | 10 ++--- block/io.c | 2 - block/io_uring.c | 4 +- block/iscsi.c | 3 +- block/linux-aio.c | 4 +- block/nfs.c | 5 +-- block/nvme.c | 8 ++-- block/ssh.c | 4 +- block/win32-aio.c | 6 +-- hw/i386/kvm/xen_xenstore.c | 2 +- hw/virtio/virtio.c | 6 +-- hw/xen/xen-bus.c | 8 ++-- io/channel-command.c | 6 +-- io/channel-file.c | 3 +- io/channel-socket.c | 3 +- migration/rdma.c | 16 ++++---- tests/unit/test-aio.c | 27 +------------ tests/unit/test-bdrv-drain.c | 1 - tests/unit/test-fdmon-epoll.c | 73 ----------------------------------- util/aio-posix.c | 20 +++------- util/aio-win32.c | 8 +--- util/async.c | 3 +- util/fdmon-epoll.c | 18 +++------ util/fdmon-io_uring.c | 8 +--- util/fdmon-poll.c | 3 +- util/main-loop.c | 7 ++-- util/qemu-coroutine-io.c | 7 ++-- util/vhost-user-server.c | 11 +++--- tests/unit/meson.build | 3 -- 35 files changed, 82 insertions(+), 295 deletions(-) delete mode 100644 tests/unit/test-fdmon-epoll.c diff --git a/include/block/aio.h b/include/block/aio.h index 89bbc536f9..32042e8905 100644 --- a/include/block/aio.h +++ b/include/block/aio.h @@ -225,8 +225,6 @@ struct AioContext { */ QEMUTimerListGroup tlg; - int external_disable_cnt; - /* Number of AioHandlers without .io_poll() */ int poll_disable_cnt; @@ -481,7 +479,6 @@ bool aio_poll(AioContext *ctx, bool blocking); */ void aio_set_fd_handler(AioContext *ctx, int fd, - bool is_external, IOHandler *io_read, IOHandler *io_write, AioPollFn *io_poll, @@ -497,7 +494,6 @@ void aio_set_fd_handler(AioContext *ctx, */ void aio_set_event_notifier(AioContext *ctx, EventNotifier *notifier, - bool is_external, EventNotifierHandler *io_read, AioPollFn *io_poll, EventNotifierHandler *io_poll_ready); @@ -626,59 +622,6 @@ static inline void aio_timer_init(AioContext *ctx, */ int64_t aio_compute_timeout(AioContext *ctx); -/** - * aio_disable_external: - * @ctx: the aio context - * - * Disable the further processing of external clients. - */ -static inline void aio_disable_external(AioContext *ctx) -{ - qatomic_inc(&ctx->external_disable_cnt); -} - -/** - * aio_enable_external: - * @ctx: the aio context - * - * Enable the processing of external clients. - */ -static inline void aio_enable_external(AioContext *ctx) -{ - int old; - - old = qatomic_fetch_dec(&ctx->external_disable_cnt); - assert(old > 0); - if (old == 1) { - /* Kick event loop so it re-arms file descriptors */ - aio_notify(ctx); - } -} - -/** - * aio_external_disabled: - * @ctx: the aio context - * - * Return true if the external clients are disabled. - */ -static inline bool aio_external_disabled(AioContext *ctx) -{ - return qatomic_read(&ctx->external_disable_cnt); -} - -/** - * aio_node_check: - * @ctx: the aio context - * @is_external: Whether or not the checked node is an external event source. - * - * Check if the node's is_external flag is okay to be polled by the ctx at this - * moment. True means green light. - */ -static inline bool aio_node_check(AioContext *ctx, bool is_external) -{ - return !is_external || !qatomic_read(&ctx->external_disable_cnt); -} - /** * aio_co_schedule: * @ctx: the aio context diff --git a/util/aio-posix.h b/util/aio-posix.h index 80b927c7f4..4264c518be 100644 --- a/util/aio-posix.h +++ b/util/aio-posix.h @@ -38,7 +38,6 @@ struct AioHandler { #endif int64_t poll_idle_timeout; /* when to stop userspace polling */ bool poll_ready; /* has polling detected an event? */ - bool is_external; }; /* Add a handler to a ready list */ diff --git a/block.c b/block.c index 5ec1a3897e..6239c8bc07 100644 --- a/block.c +++ b/block.c @@ -7268,9 +7268,6 @@ static void bdrv_detach_aio_context(BlockDriverState *bs) bs->drv->bdrv_detach_aio_context(bs); } - if (bs->quiesce_counter) { - aio_enable_external(bs->aio_context); - } bs->aio_context = NULL; } @@ -7280,10 +7277,6 @@ static void bdrv_attach_aio_context(BlockDriverState *bs, BdrvAioNotifier *ban, *ban_tmp; GLOBAL_STATE_CODE(); - if (bs->quiesce_counter) { - aio_disable_external(new_context); - } - bs->aio_context = new_context; if (bs->drv && bs->drv->bdrv_attach_aio_context) { diff --git a/block/blkio.c b/block/blkio.c index 0cdc99a729..72117fa005 100644 --- a/block/blkio.c +++ b/block/blkio.c @@ -306,23 +306,18 @@ static void blkio_attach_aio_context(BlockDriverState *bs, { BDRVBlkioState *s = bs->opaque; - aio_set_fd_handler(new_context, - s->completion_fd, - false, - blkio_completion_fd_read, - NULL, + aio_set_fd_handler(new_context, s->completion_fd, + blkio_completion_fd_read, NULL, blkio_completion_fd_poll, - blkio_completion_fd_poll_ready, - bs); + blkio_completion_fd_poll_ready, bs); } static void blkio_detach_aio_context(BlockDriverState *bs) { BDRVBlkioState *s = bs->opaque; - aio_set_fd_handler(bdrv_get_aio_context(bs), - s->completion_fd, - false, NULL, NULL, NULL, NULL, NULL); + aio_set_fd_handler(bdrv_get_aio_context(bs), s->completion_fd, NULL, NULL, + NULL, NULL, NULL); } /* Call with s->blkio_lock held to submit I/O after enqueuing a new request */ diff --git a/block/curl.c b/block/curl.c index 8bb39a134e..0fc42d03d7 100644 --- a/block/curl.c +++ b/block/curl.c @@ -132,7 +132,7 @@ static gboolean curl_drop_socket(void *key, void *value, void *opaque) CURLSocket *socket = value; BDRVCURLState *s = socket->s; - aio_set_fd_handler(s->aio_context, socket->fd, false, + aio_set_fd_handler(s->aio_context, socket->fd, NULL, NULL, NULL, NULL, NULL); return true; } @@ -180,20 +180,20 @@ static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action, trace_curl_sock_cb(action, (int)fd); switch (action) { case CURL_POLL_IN: - aio_set_fd_handler(s->aio_context, fd, false, + aio_set_fd_handler(s->aio_context, fd, curl_multi_do, NULL, NULL, NULL, socket); break; case CURL_POLL_OUT: - aio_set_fd_handler(s->aio_context, fd, false, + aio_set_fd_handler(s->aio_context, fd, NULL, curl_multi_do, NULL, NULL, socket); break; case CURL_POLL_INOUT: - aio_set_fd_handler(s->aio_context, fd, false, + aio_set_fd_handler(s->aio_context, fd, curl_multi_do, curl_multi_do, NULL, NULL, socket); break; case CURL_POLL_REMOVE: - aio_set_fd_handler(s->aio_context, fd, false, + aio_set_fd_handler(s->aio_context, fd, NULL, NULL, NULL, NULL, NULL); break; } diff --git a/block/export/fuse.c b/block/export/fuse.c index adf3236b5a..3307b64089 100644 --- a/block/export/fuse.c +++ b/block/export/fuse.c @@ -84,7 +84,7 @@ static void fuse_export_drained_begin(void *opaque) FuseExport *exp = opaque; aio_set_fd_handler(exp->common.ctx, - fuse_session_fd(exp->fuse_session), false, + fuse_session_fd(exp->fuse_session), NULL, NULL, NULL, NULL, NULL); exp->fd_handler_set_up = false; } @@ -97,7 +97,7 @@ static void fuse_export_drained_end(void *opaque) exp->common.ctx = blk_get_aio_context(exp->common.blk); aio_set_fd_handler(exp->common.ctx, - fuse_session_fd(exp->fuse_session), false, + fuse_session_fd(exp->fuse_session), read_from_fuse_export, NULL, NULL, NULL, exp); exp->fd_handler_set_up = true; } @@ -270,7 +270,7 @@ static int setup_fuse_export(FuseExport *exp, const char *mountpoint, g_hash_table_insert(exports, g_strdup(mountpoint), NULL); aio_set_fd_handler(exp->common.ctx, - fuse_session_fd(exp->fuse_session), false, + fuse_session_fd(exp->fuse_session), read_from_fuse_export, NULL, NULL, NULL, exp); exp->fd_handler_set_up = true; @@ -320,7 +320,7 @@ static void fuse_export_shutdown(BlockExport *blk_exp) if (exp->fd_handler_set_up) { aio_set_fd_handler(exp->common.ctx, - fuse_session_fd(exp->fuse_session), false, + fuse_session_fd(exp->fuse_session), NULL, NULL, NULL, NULL, NULL); exp->fd_handler_set_up = false; } diff --git a/block/export/vduse-blk.c b/block/export/vduse-blk.c index e0455551f9..83b05548e7 100644 --- a/block/export/vduse-blk.c +++ b/block/export/vduse-blk.c @@ -137,7 +137,7 @@ static void vduse_blk_enable_queue(VduseDev *dev, VduseVirtq *vq) } aio_set_fd_handler(vblk_exp->export.ctx, vduse_queue_get_fd(vq), - false, on_vduse_vq_kick, NULL, NULL, NULL, vq); + on_vduse_vq_kick, NULL, NULL, NULL, vq); /* Make sure we don't miss any kick afer reconnecting */ eventfd_write(vduse_queue_get_fd(vq), 1); } @@ -151,7 +151,7 @@ static void vduse_blk_disable_queue(VduseDev *dev, VduseVirtq *vq) return; } - aio_set_fd_handler(vblk_exp->export.ctx, fd, false, + aio_set_fd_handler(vblk_exp->export.ctx, fd, NULL, NULL, NULL, NULL, NULL); } @@ -170,7 +170,7 @@ static void on_vduse_dev_kick(void *opaque) static void vduse_blk_attach_ctx(VduseBlkExport *vblk_exp, AioContext *ctx) { aio_set_fd_handler(vblk_exp->export.ctx, vduse_dev_get_fd(vblk_exp->dev), - false, on_vduse_dev_kick, NULL, NULL, NULL, + on_vduse_dev_kick, NULL, NULL, NULL, vblk_exp->dev); /* Virtqueues are handled by vduse_blk_drained_end() */ @@ -179,7 +179,7 @@ static void vduse_blk_attach_ctx(VduseBlkExport *vblk_exp, AioContext *ctx) static void vduse_blk_detach_ctx(VduseBlkExport *vblk_exp) { aio_set_fd_handler(vblk_exp->export.ctx, vduse_dev_get_fd(vblk_exp->dev), - false, NULL, NULL, NULL, NULL, NULL); + NULL, NULL, NULL, NULL, NULL); /* Virtqueues are handled by vduse_blk_drained_begin() */ } @@ -364,7 +364,7 @@ static int vduse_blk_exp_create(BlockExport *exp, BlockExportOptions *opts, vduse_dev_setup_queue(vblk_exp->dev, i, queue_size); } - aio_set_fd_handler(exp->ctx, vduse_dev_get_fd(vblk_exp->dev), false, + aio_set_fd_handler(exp->ctx, vduse_dev_get_fd(vblk_exp->dev), on_vduse_dev_kick, NULL, NULL, NULL, vblk_exp->dev); blk_add_aio_context_notifier(exp->blk, blk_aio_attached, blk_aio_detach, diff --git a/block/io.c b/block/io.c index 532c8c90c9..9f82d1009e 100644 --- a/block/io.c +++ b/block/io.c @@ -363,7 +363,6 @@ static void bdrv_do_drained_begin(BlockDriverState *bs, BdrvChild *parent, /* Stop things in parent-to-child order */ if (qatomic_fetch_inc(&bs->quiesce_counter) == 0) { - aio_disable_external(bdrv_get_aio_context(bs)); bdrv_parent_drained_begin(bs, parent); if (bs->drv && bs->drv->bdrv_drain_begin) { bs->drv->bdrv_drain_begin(bs); @@ -419,7 +418,6 @@ static void bdrv_do_drained_end(BlockDriverState *bs, BdrvChild *parent) bs->drv->bdrv_drain_end(bs); } bdrv_parent_drained_end(bs, parent); - aio_enable_external(bdrv_get_aio_context(bs)); } } diff --git a/block/io_uring.c b/block/io_uring.c index 989f9a99ed..b64a3e6285 100644 --- a/block/io_uring.c +++ b/block/io_uring.c @@ -406,7 +406,7 @@ int coroutine_fn luring_co_submit(BlockDriverState *bs, int fd, uint64_t offset, void luring_detach_aio_context(LuringState *s, AioContext *old_context) { - aio_set_fd_handler(old_context, s->ring.ring_fd, false, + aio_set_fd_handler(old_context, s->ring.ring_fd, NULL, NULL, NULL, NULL, s); qemu_bh_delete(s->completion_bh); s->aio_context = NULL; @@ -416,7 +416,7 @@ void luring_attach_aio_context(LuringState *s, AioContext *new_context) { s->aio_context = new_context; s->completion_bh = aio_bh_new(new_context, qemu_luring_completion_bh, s); - aio_set_fd_handler(s->aio_context, s->ring.ring_fd, false, + aio_set_fd_handler(s->aio_context, s->ring.ring_fd, qemu_luring_completion_cb, NULL, qemu_luring_poll_cb, qemu_luring_poll_ready, s); } diff --git a/block/iscsi.c b/block/iscsi.c index 9fc0bed90b..34f97ab646 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -363,7 +363,6 @@ iscsi_set_events(IscsiLun *iscsilun) if (ev != iscsilun->events) { aio_set_fd_handler(iscsilun->aio_context, iscsi_get_fd(iscsi), - false, (ev & POLLIN) ? iscsi_process_read : NULL, (ev & POLLOUT) ? iscsi_process_write : NULL, NULL, NULL, @@ -1540,7 +1539,7 @@ static void iscsi_detach_aio_context(BlockDriverState *bs) IscsiLun *iscsilun = bs->opaque; aio_set_fd_handler(iscsilun->aio_context, iscsi_get_fd(iscsilun->iscsi), - false, NULL, NULL, NULL, NULL, NULL); + NULL, NULL, NULL, NULL, NULL); iscsilun->events = 0; if (iscsilun->nop_timer) { diff --git a/block/linux-aio.c b/block/linux-aio.c index fc50cdd1bf..129908531a 100644 --- a/block/linux-aio.c +++ b/block/linux-aio.c @@ -443,7 +443,7 @@ int coroutine_fn laio_co_submit(int fd, uint64_t offset, QEMUIOVector *qiov, void laio_detach_aio_context(LinuxAioState *s, AioContext *old_context) { - aio_set_event_notifier(old_context, &s->e, false, NULL, NULL, NULL); + aio_set_event_notifier(old_context, &s->e, NULL, NULL, NULL); qemu_bh_delete(s->completion_bh); s->aio_context = NULL; } @@ -452,7 +452,7 @@ void laio_attach_aio_context(LinuxAioState *s, AioContext *new_context) { s->aio_context = new_context; s->completion_bh = aio_bh_new(new_context, qemu_laio_completion_bh, s); - aio_set_event_notifier(new_context, &s->e, false, + aio_set_event_notifier(new_context, &s->e, qemu_laio_completion_cb, qemu_laio_poll_cb, qemu_laio_poll_ready); diff --git a/block/nfs.c b/block/nfs.c index 006045d71a..8f89ece69f 100644 --- a/block/nfs.c +++ b/block/nfs.c @@ -195,7 +195,6 @@ static void nfs_set_events(NFSClient *client) int ev = nfs_which_events(client->context); if (ev != client->events) { aio_set_fd_handler(client->aio_context, nfs_get_fd(client->context), - false, (ev & POLLIN) ? nfs_process_read : NULL, (ev & POLLOUT) ? nfs_process_write : NULL, NULL, NULL, client); @@ -373,7 +372,7 @@ static void nfs_detach_aio_context(BlockDriverState *bs) NFSClient *client = bs->opaque; aio_set_fd_handler(client->aio_context, nfs_get_fd(client->context), - false, NULL, NULL, NULL, NULL, NULL); + NULL, NULL, NULL, NULL, NULL); client->events = 0; } @@ -391,7 +390,7 @@ static void nfs_client_close(NFSClient *client) if (client->context) { qemu_mutex_lock(&client->mutex); aio_set_fd_handler(client->aio_context, nfs_get_fd(client->context), - false, NULL, NULL, NULL, NULL, NULL); + NULL, NULL, NULL, NULL, NULL); qemu_mutex_unlock(&client->mutex); if (client->fh) { nfs_close(client->context, client->fh); diff --git a/block/nvme.c b/block/nvme.c index 5b744c2bda..17937d398d 100644 --- a/block/nvme.c +++ b/block/nvme.c @@ -862,7 +862,7 @@ static int nvme_init(BlockDriverState *bs, const char *device, int namespace, } aio_set_event_notifier(bdrv_get_aio_context(bs), &s->irq_notifier[MSIX_SHARED_IRQ_IDX], - false, nvme_handle_event, nvme_poll_cb, + nvme_handle_event, nvme_poll_cb, nvme_poll_ready); if (!nvme_identify(bs, namespace, errp)) { @@ -948,7 +948,7 @@ static void nvme_close(BlockDriverState *bs) g_free(s->queues); aio_set_event_notifier(bdrv_get_aio_context(bs), &s->irq_notifier[MSIX_SHARED_IRQ_IDX], - false, NULL, NULL, NULL); + NULL, NULL, NULL); event_notifier_cleanup(&s->irq_notifier[MSIX_SHARED_IRQ_IDX]); qemu_vfio_pci_unmap_bar(s->vfio, 0, s->bar0_wo_map, 0, sizeof(NvmeBar) + NVME_DOORBELL_SIZE); @@ -1546,7 +1546,7 @@ static void nvme_detach_aio_context(BlockDriverState *bs) aio_set_event_notifier(bdrv_get_aio_context(bs), &s->irq_notifier[MSIX_SHARED_IRQ_IDX], - false, NULL, NULL, NULL); + NULL, NULL, NULL); } static void nvme_attach_aio_context(BlockDriverState *bs, @@ -1556,7 +1556,7 @@ static void nvme_attach_aio_context(BlockDriverState *bs, s->aio_context = new_context; aio_set_event_notifier(new_context, &s->irq_notifier[MSIX_SHARED_IRQ_IDX], - false, nvme_handle_event, nvme_poll_cb, + nvme_handle_event, nvme_poll_cb, nvme_poll_ready); for (unsigned i = 0; i < s->queue_count; i++) { diff --git a/block/ssh.c b/block/ssh.c index b3b3352075..2748253d4a 100644 --- a/block/ssh.c +++ b/block/ssh.c @@ -1019,7 +1019,7 @@ static void restart_coroutine(void *opaque) AioContext *ctx = bdrv_get_aio_context(bs); trace_ssh_restart_coroutine(restart->co); - aio_set_fd_handler(ctx, s->sock, false, NULL, NULL, NULL, NULL, NULL); + aio_set_fd_handler(ctx, s->sock, NULL, NULL, NULL, NULL, NULL); aio_co_wake(restart->co); } @@ -1049,7 +1049,7 @@ static coroutine_fn void co_yield(BDRVSSHState *s, BlockDriverState *bs) trace_ssh_co_yield(s->sock, rd_handler, wr_handler); aio_set_fd_handler(bdrv_get_aio_context(bs), s->sock, - false, rd_handler, wr_handler, NULL, NULL, &restart); + rd_handler, wr_handler, NULL, NULL, &restart); qemu_coroutine_yield(); trace_ssh_co_yield_back(s->sock); } diff --git a/block/win32-aio.c b/block/win32-aio.c index ee87d6048f..6327861e1d 100644 --- a/block/win32-aio.c +++ b/block/win32-aio.c @@ -174,7 +174,7 @@ int win32_aio_attach(QEMUWin32AIOState *aio, HANDLE hfile) void win32_aio_detach_aio_context(QEMUWin32AIOState *aio, AioContext *old_context) { - aio_set_event_notifier(old_context, &aio->e, false, NULL, NULL, NULL); + aio_set_event_notifier(old_context, &aio->e, NULL, NULL, NULL); aio->aio_ctx = NULL; } @@ -182,8 +182,8 @@ void win32_aio_attach_aio_context(QEMUWin32AIOState *aio, AioContext *new_context) { aio->aio_ctx = new_context; - aio_set_event_notifier(new_context, &aio->e, false, - win32_aio_completion_cb, NULL, NULL); + aio_set_event_notifier(new_context, &aio->e, win32_aio_completion_cb, + NULL, NULL); } QEMUWin32AIOState *win32_aio_init(void) diff --git a/hw/i386/kvm/xen_xenstore.c b/hw/i386/kvm/xen_xenstore.c index 6e81bc8791..0b189c6ab8 100644 --- a/hw/i386/kvm/xen_xenstore.c +++ b/hw/i386/kvm/xen_xenstore.c @@ -133,7 +133,7 @@ static void xen_xenstore_realize(DeviceState *dev, Error **errp) error_setg(errp, "Xenstore evtchn port init failed"); return; } - aio_set_fd_handler(qemu_get_aio_context(), xen_be_evtchn_fd(s->eh), false, + aio_set_fd_handler(qemu_get_aio_context(), xen_be_evtchn_fd(s->eh), xen_xenstore_event, NULL, NULL, NULL, s); s->impl = xs_impl_create(xen_domid); diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 9cdad7e550..d48e240c37 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -3491,7 +3491,7 @@ static void virtio_queue_host_notifier_aio_poll_end(EventNotifier *n) void virtio_queue_aio_attach_host_notifier(VirtQueue *vq, AioContext *ctx) { - aio_set_event_notifier(ctx, &vq->host_notifier, false, + aio_set_event_notifier(ctx, &vq->host_notifier, virtio_queue_host_notifier_read, virtio_queue_host_notifier_aio_poll, virtio_queue_host_notifier_aio_poll_ready); @@ -3508,14 +3508,14 @@ void virtio_queue_aio_attach_host_notifier(VirtQueue *vq, AioContext *ctx) */ void virtio_queue_aio_attach_host_notifier_no_poll(VirtQueue *vq, AioContext *ctx) { - aio_set_event_notifier(ctx, &vq->host_notifier, false, + aio_set_event_notifier(ctx, &vq->host_notifier, virtio_queue_host_notifier_read, NULL, NULL); } void virtio_queue_aio_detach_host_notifier(VirtQueue *vq, AioContext *ctx) { - aio_set_event_notifier(ctx, &vq->host_notifier, false, NULL, NULL, NULL); + aio_set_event_notifier(ctx, &vq->host_notifier, NULL, NULL, NULL); /* Test and clear notifier before after disabling event, * in case poll callback didn't have time to run. */ virtio_queue_host_notifier_read(&vq->host_notifier); diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c index bf256d4da2..1e08cf027a 100644 --- a/hw/xen/xen-bus.c +++ b/hw/xen/xen-bus.c @@ -842,14 +842,14 @@ void xen_device_set_event_channel_context(XenDevice *xendev, } if (channel->ctx) - aio_set_fd_handler(channel->ctx, qemu_xen_evtchn_fd(channel->xeh), false, + aio_set_fd_handler(channel->ctx, qemu_xen_evtchn_fd(channel->xeh), NULL, NULL, NULL, NULL, NULL); channel->ctx = ctx; if (ctx) { aio_set_fd_handler(channel->ctx, qemu_xen_evtchn_fd(channel->xeh), - false, xen_device_event, NULL, xen_device_poll, - NULL, channel); + xen_device_event, NULL, xen_device_poll, NULL, + channel); } } @@ -923,7 +923,7 @@ void xen_device_unbind_event_channel(XenDevice *xendev, QLIST_REMOVE(channel, list); - aio_set_fd_handler(channel->ctx, qemu_xen_evtchn_fd(channel->xeh), false, + aio_set_fd_handler(channel->ctx, qemu_xen_evtchn_fd(channel->xeh), NULL, NULL, NULL, NULL, NULL); if (qemu_xen_evtchn_unbind(channel->xeh, channel->local_port) < 0) { diff --git a/io/channel-command.c b/io/channel-command.c index e7edd091af..7ed726c802 100644 --- a/io/channel-command.c +++ b/io/channel-command.c @@ -337,10 +337,8 @@ static void qio_channel_command_set_aio_fd_handler(QIOChannel *ioc, void *opaque) { QIOChannelCommand *cioc = QIO_CHANNEL_COMMAND(ioc); - aio_set_fd_handler(ctx, cioc->readfd, false, - io_read, NULL, NULL, NULL, opaque); - aio_set_fd_handler(ctx, cioc->writefd, false, - NULL, io_write, NULL, NULL, opaque); + aio_set_fd_handler(ctx, cioc->readfd, io_read, NULL, NULL, NULL, opaque); + aio_set_fd_handler(ctx, cioc->writefd, NULL, io_write, NULL, NULL, opaque); } diff --git a/io/channel-file.c b/io/channel-file.c index d76663e6ae..8b5821f452 100644 --- a/io/channel-file.c +++ b/io/channel-file.c @@ -198,8 +198,7 @@ static void qio_channel_file_set_aio_fd_handler(QIOChannel *ioc, void *opaque) { QIOChannelFile *fioc = QIO_CHANNEL_FILE(ioc); - aio_set_fd_handler(ctx, fioc->fd, false, io_read, io_write, - NULL, NULL, opaque); + aio_set_fd_handler(ctx, fioc->fd, io_read, io_write, NULL, NULL, opaque); } static GSource *qio_channel_file_create_watch(QIOChannel *ioc, diff --git a/io/channel-socket.c b/io/channel-socket.c index b0ea7d48b3..d99945ebec 100644 --- a/io/channel-socket.c +++ b/io/channel-socket.c @@ -899,8 +899,7 @@ static void qio_channel_socket_set_aio_fd_handler(QIOChannel *ioc, void *opaque) { QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc); - aio_set_fd_handler(ctx, sioc->fd, false, - io_read, io_write, NULL, NULL, opaque); + aio_set_fd_handler(ctx, sioc->fd, io_read, io_write, NULL, NULL, opaque); } static GSource *qio_channel_socket_create_watch(QIOChannel *ioc, diff --git a/migration/rdma.c b/migration/rdma.c index 7e747b2595..afb8761a06 100644 --- a/migration/rdma.c +++ b/migration/rdma.c @@ -3110,15 +3110,15 @@ static void qio_channel_rdma_set_aio_fd_handler(QIOChannel *ioc, { QIOChannelRDMA *rioc = QIO_CHANNEL_RDMA(ioc); if (io_read) { - aio_set_fd_handler(ctx, rioc->rdmain->recv_comp_channel->fd, - false, io_read, io_write, NULL, NULL, opaque); - aio_set_fd_handler(ctx, rioc->rdmain->send_comp_channel->fd, - false, io_read, io_write, NULL, NULL, opaque); + aio_set_fd_handler(ctx, rioc->rdmain->recv_comp_channel->fd, io_read, + io_write, NULL, NULL, opaque); + aio_set_fd_handler(ctx, rioc->rdmain->send_comp_channel->fd, io_read, + io_write, NULL, NULL, opaque); } else { - aio_set_fd_handler(ctx, rioc->rdmaout->recv_comp_channel->fd, - false, io_read, io_write, NULL, NULL, opaque); - aio_set_fd_handler(ctx, rioc->rdmaout->send_comp_channel->fd, - false, io_read, io_write, NULL, NULL, opaque); + aio_set_fd_handler(ctx, rioc->rdmaout->recv_comp_channel->fd, io_read, + io_write, NULL, NULL, opaque); + aio_set_fd_handler(ctx, rioc->rdmaout->send_comp_channel->fd, io_read, + io_write, NULL, NULL, opaque); } } diff --git a/tests/unit/test-aio.c b/tests/unit/test-aio.c index 321d7ab01a..519440eed3 100644 --- a/tests/unit/test-aio.c +++ b/tests/unit/test-aio.c @@ -130,7 +130,7 @@ static void *test_acquire_thread(void *opaque) static void set_event_notifier(AioContext *ctx, EventNotifier *notifier, EventNotifierHandler *handler) { - aio_set_event_notifier(ctx, notifier, false, handler, NULL, NULL); + aio_set_event_notifier(ctx, notifier, handler, NULL, NULL); } static void dummy_notifier_read(EventNotifier *n) @@ -383,30 +383,6 @@ static void test_flush_event_notifier(void) event_notifier_cleanup(&data.e); } -static void test_aio_external_client(void) -{ - int i, j; - - for (i = 1; i < 3; i++) { - EventNotifierTestData data = { .n = 0, .active = 10, .auto_set = true }; - event_notifier_init(&data.e, false); - aio_set_event_notifier(ctx, &data.e, true, event_ready_cb, NULL, NULL); - event_notifier_set(&data.e); - for (j = 0; j < i; j++) { - aio_disable_external(ctx); - } - for (j = 0; j < i; j++) { - assert(!aio_poll(ctx, false)); - assert(event_notifier_test_and_clear(&data.e)); - event_notifier_set(&data.e); - aio_enable_external(ctx); - } - assert(aio_poll(ctx, false)); - set_event_notifier(ctx, &data.e, NULL); - event_notifier_cleanup(&data.e); - } -} - static void test_wait_event_notifier_noflush(void) { EventNotifierTestData data = { .n = 0 }; @@ -935,7 +911,6 @@ int main(int argc, char **argv) g_test_add_func("/aio/event/wait", test_wait_event_notifier); g_test_add_func("/aio/event/wait/no-flush-cb", test_wait_event_notifier_noflush); g_test_add_func("/aio/event/flush", test_flush_event_notifier); - g_test_add_func("/aio/external-client", test_aio_external_client); g_test_add_func("/aio/timer/schedule", test_timer_schedule); g_test_add_func("/aio/coroutine/queue-chaining", test_queue_chaining); diff --git a/tests/unit/test-bdrv-drain.c b/tests/unit/test-bdrv-drain.c index dc3cb9e0e3..9cac61c2bf 100644 --- a/tests/unit/test-bdrv-drain.c +++ b/tests/unit/test-bdrv-drain.c @@ -435,7 +435,6 @@ static void test_graph_change_drain_all(void) g_assert_cmpint(bs_b->quiesce_counter, ==, 0); g_assert_cmpint(b_s->drain_count, ==, 0); - g_assert_cmpint(qemu_get_aio_context()->external_disable_cnt, ==, 0); bdrv_unref(bs_b); blk_unref(blk_b); diff --git a/tests/unit/test-fdmon-epoll.c b/tests/unit/test-fdmon-epoll.c deleted file mode 100644 index ef5a856d09..0000000000 --- a/tests/unit/test-fdmon-epoll.c +++ /dev/null @@ -1,73 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * fdmon-epoll tests - * - * Copyright (c) 2020 Red Hat, Inc. - */ - -#include "qemu/osdep.h" -#include "block/aio.h" -#include "qapi/error.h" -#include "qemu/main-loop.h" - -static AioContext *ctx; - -static void dummy_fd_handler(EventNotifier *notifier) -{ - event_notifier_test_and_clear(notifier); -} - -static void add_event_notifiers(EventNotifier *notifiers, size_t n) -{ - for (size_t i = 0; i < n; i++) { - event_notifier_init(¬ifiers[i], false); - aio_set_event_notifier(ctx, ¬ifiers[i], false, - dummy_fd_handler, NULL, NULL); - } -} - -static void remove_event_notifiers(EventNotifier *notifiers, size_t n) -{ - for (size_t i = 0; i < n; i++) { - aio_set_event_notifier(ctx, ¬ifiers[i], false, NULL, NULL, NULL); - event_notifier_cleanup(¬ifiers[i]); - } -} - -/* Check that fd handlers work when external clients are disabled */ -static void test_external_disabled(void) -{ - EventNotifier notifiers[100]; - - /* fdmon-epoll is only enabled when many fd handlers are registered */ - add_event_notifiers(notifiers, G_N_ELEMENTS(notifiers)); - - event_notifier_set(¬ifiers[0]); - assert(aio_poll(ctx, true)); - - aio_disable_external(ctx); - event_notifier_set(¬ifiers[0]); - assert(aio_poll(ctx, true)); - aio_enable_external(ctx); - - remove_event_notifiers(notifiers, G_N_ELEMENTS(notifiers)); -} - -int main(int argc, char **argv) -{ - /* - * This code relies on the fact that fdmon-io_uring disables itself when - * the glib main loop is in use. The main loop uses fdmon-poll and upgrades - * to fdmon-epoll when the number of fds exceeds a threshold. - */ - qemu_init_main_loop(&error_fatal); - ctx = qemu_get_aio_context(); - - while (g_main_context_iteration(NULL, false)) { - /* Do nothing */ - } - - g_test_init(&argc, &argv, NULL); - g_test_add_func("/fdmon-epoll/external-disabled", test_external_disabled); - return g_test_run(); -} diff --git a/util/aio-posix.c b/util/aio-posix.c index a8be940f76..934b1bbb85 100644 --- a/util/aio-posix.c +++ b/util/aio-posix.c @@ -99,7 +99,6 @@ static bool aio_remove_fd_handler(AioContext *ctx, AioHandler *node) void aio_set_fd_handler(AioContext *ctx, int fd, - bool is_external, IOHandler *io_read, IOHandler *io_write, AioPollFn *io_poll, @@ -144,7 +143,6 @@ void aio_set_fd_handler(AioContext *ctx, new_node->io_poll = io_poll; new_node->io_poll_ready = io_poll_ready; new_node->opaque = opaque; - new_node->is_external = is_external; if (is_new) { new_node->pfd.fd = fd; @@ -196,12 +194,11 @@ static void aio_set_fd_poll(AioContext *ctx, int fd, void aio_set_event_notifier(AioContext *ctx, EventNotifier *notifier, - bool is_external, EventNotifierHandler *io_read, AioPollFn *io_poll, EventNotifierHandler *io_poll_ready) { - aio_set_fd_handler(ctx, event_notifier_get_fd(notifier), is_external, + aio_set_fd_handler(ctx, event_notifier_get_fd(notifier), (IOHandler *)io_read, NULL, io_poll, (IOHandler *)io_poll_ready, notifier); } @@ -285,13 +282,11 @@ bool aio_pending(AioContext *ctx) /* TODO should this check poll ready? */ revents = node->pfd.revents & node->pfd.events; - if (revents & (G_IO_IN | G_IO_HUP | G_IO_ERR) && node->io_read && - aio_node_check(ctx, node->is_external)) { + if (revents & (G_IO_IN | G_IO_HUP | G_IO_ERR) && node->io_read) { result = true; break; } - if (revents & (G_IO_OUT | G_IO_ERR) && node->io_write && - aio_node_check(ctx, node->is_external)) { + if (revents & (G_IO_OUT | G_IO_ERR) && node->io_write) { result = true; break; } @@ -350,9 +345,7 @@ static bool aio_dispatch_handler(AioContext *ctx, AioHandler *node) QLIST_INSERT_HEAD(&ctx->poll_aio_handlers, node, node_poll); } if (!QLIST_IS_INSERTED(node, node_deleted) && - poll_ready && revents == 0 && - aio_node_check(ctx, node->is_external) && - node->io_poll_ready) { + poll_ready && revents == 0 && node->io_poll_ready) { node->io_poll_ready(node->opaque); /* @@ -364,7 +357,6 @@ static bool aio_dispatch_handler(AioContext *ctx, AioHandler *node) if (!QLIST_IS_INSERTED(node, node_deleted) && (revents & (G_IO_IN | G_IO_HUP | G_IO_ERR)) && - aio_node_check(ctx, node->is_external) && node->io_read) { node->io_read(node->opaque); @@ -375,7 +367,6 @@ static bool aio_dispatch_handler(AioContext *ctx, AioHandler *node) } if (!QLIST_IS_INSERTED(node, node_deleted) && (revents & (G_IO_OUT | G_IO_ERR)) && - aio_node_check(ctx, node->is_external) && node->io_write) { node->io_write(node->opaque); progress = true; @@ -436,8 +427,7 @@ static bool run_poll_handlers_once(AioContext *ctx, AioHandler *tmp; QLIST_FOREACH_SAFE(node, &ctx->poll_aio_handlers, node_poll, tmp) { - if (aio_node_check(ctx, node->is_external) && - node->io_poll(node->opaque)) { + if (node->io_poll(node->opaque)) { aio_add_poll_ready_handler(ready_list, node); node->poll_idle_timeout = now + POLL_IDLE_INTERVAL_NS; diff --git a/util/aio-win32.c b/util/aio-win32.c index 6bded009a4..948ef47a4d 100644 --- a/util/aio-win32.c +++ b/util/aio-win32.c @@ -32,7 +32,6 @@ struct AioHandler { GPollFD pfd; int deleted; void *opaque; - bool is_external; QLIST_ENTRY(AioHandler) node; }; @@ -64,7 +63,6 @@ static void aio_remove_fd_handler(AioContext *ctx, AioHandler *node) void aio_set_fd_handler(AioContext *ctx, int fd, - bool is_external, IOHandler *io_read, IOHandler *io_write, AioPollFn *io_poll, @@ -111,7 +109,6 @@ void aio_set_fd_handler(AioContext *ctx, node->opaque = opaque; node->io_read = io_read; node->io_write = io_write; - node->is_external = is_external; if (io_read) { bitmask |= FD_READ | FD_ACCEPT | FD_CLOSE; @@ -135,7 +132,6 @@ void aio_set_fd_handler(AioContext *ctx, void aio_set_event_notifier(AioContext *ctx, EventNotifier *e, - bool is_external, EventNotifierHandler *io_notify, AioPollFn *io_poll, EventNotifierHandler *io_poll_ready) @@ -161,7 +157,6 @@ void aio_set_event_notifier(AioContext *ctx, node->e = e; node->pfd.fd = (uintptr_t)event_notifier_get_handle(e); node->pfd.events = G_IO_IN; - node->is_external = is_external; QLIST_INSERT_HEAD_RCU(&ctx->aio_handlers, node, node); g_source_add_poll(&ctx->source, &node->pfd); @@ -368,8 +363,7 @@ bool aio_poll(AioContext *ctx, bool blocking) /* fill fd sets */ count = 0; QLIST_FOREACH_RCU(node, &ctx->aio_handlers, node) { - if (!node->deleted && node->io_notify - && aio_node_check(ctx, node->is_external)) { + if (!node->deleted && node->io_notify) { assert(count < MAXIMUM_WAIT_OBJECTS); events[count++] = event_notifier_get_handle(node->e); } diff --git a/util/async.c b/util/async.c index 055070ffbd..8f90ddc304 100644 --- a/util/async.c +++ b/util/async.c @@ -409,7 +409,7 @@ aio_ctx_finalize(GSource *source) g_free(bh); } - aio_set_event_notifier(ctx, &ctx->notifier, false, NULL, NULL, NULL); + aio_set_event_notifier(ctx, &ctx->notifier, NULL, NULL, NULL); event_notifier_cleanup(&ctx->notifier); qemu_rec_mutex_destroy(&ctx->lock); qemu_lockcnt_destroy(&ctx->list_lock); @@ -593,7 +593,6 @@ AioContext *aio_context_new(Error **errp) QSLIST_INIT(&ctx->scheduled_coroutines); aio_set_event_notifier(ctx, &ctx->notifier, - false, aio_context_notifier_cb, aio_context_notifier_poll, aio_context_notifier_poll_ready); diff --git a/util/fdmon-epoll.c b/util/fdmon-epoll.c index 1683aa1105..6b6a1a91f8 100644 --- a/util/fdmon-epoll.c +++ b/util/fdmon-epoll.c @@ -64,11 +64,6 @@ static int fdmon_epoll_wait(AioContext *ctx, AioHandlerList *ready_list, int i, ret = 0; struct epoll_event events[128]; - /* Fall back while external clients are disabled */ - if (qatomic_read(&ctx->external_disable_cnt)) { - return fdmon_poll_ops.wait(ctx, ready_list, timeout); - } - if (timeout > 0) { ret = qemu_poll_ns(&pfd, 1, timeout); if (ret > 0) { @@ -133,13 +128,12 @@ bool fdmon_epoll_try_upgrade(AioContext *ctx, unsigned npfd) return false; } - /* Do not upgrade while external clients are disabled */ - if (qatomic_read(&ctx->external_disable_cnt)) { - return false; - } - - if (npfd < EPOLL_ENABLE_THRESHOLD) { - return false; + if (npfd >= EPOLL_ENABLE_THRESHOLD) { + if (fdmon_epoll_try_enable(ctx)) { + return true; + } else { + fdmon_epoll_disable(ctx); + } } /* The list must not change while we add fds to epoll */ diff --git a/util/fdmon-io_uring.c b/util/fdmon-io_uring.c index ab43052dd7..17ec18b7bd 100644 --- a/util/fdmon-io_uring.c +++ b/util/fdmon-io_uring.c @@ -276,11 +276,6 @@ static int fdmon_io_uring_wait(AioContext *ctx, AioHandlerList *ready_list, unsigned wait_nr = 1; /* block until at least one cqe is ready */ int ret; - /* Fall back while external clients are disabled */ - if (qatomic_read(&ctx->external_disable_cnt)) { - return fdmon_poll_ops.wait(ctx, ready_list, timeout); - } - if (timeout == 0) { wait_nr = 0; /* non-blocking */ } else if (timeout > 0) { @@ -315,8 +310,7 @@ static bool fdmon_io_uring_need_wait(AioContext *ctx) return true; } - /* Are we falling back to fdmon-poll? */ - return qatomic_read(&ctx->external_disable_cnt); + return false; } static const FDMonOps fdmon_io_uring_ops = { diff --git a/util/fdmon-poll.c b/util/fdmon-poll.c index 5fe3b47865..17df917cf9 100644 --- a/util/fdmon-poll.c +++ b/util/fdmon-poll.c @@ -65,8 +65,7 @@ static int fdmon_poll_wait(AioContext *ctx, AioHandlerList *ready_list, assert(npfd == 0); QLIST_FOREACH_RCU(node, &ctx->aio_handlers, node) { - if (!QLIST_IS_INSERTED(node, node_deleted) && node->pfd.events - && aio_node_check(ctx, node->is_external)) { + if (!QLIST_IS_INSERTED(node, node_deleted) && node->pfd.events) { add_pollfd(node); } } diff --git a/util/main-loop.c b/util/main-loop.c index 7022f02ef8..014c795916 100644 --- a/util/main-loop.c +++ b/util/main-loop.c @@ -644,14 +644,13 @@ void qemu_set_fd_handler(int fd, void *opaque) { iohandler_init(); - aio_set_fd_handler(iohandler_ctx, fd, false, - fd_read, fd_write, NULL, NULL, opaque); + aio_set_fd_handler(iohandler_ctx, fd, fd_read, fd_write, NULL, NULL, + opaque); } void event_notifier_set_handler(EventNotifier *e, EventNotifierHandler *handler) { iohandler_init(); - aio_set_event_notifier(iohandler_ctx, e, false, - handler, NULL, NULL); + aio_set_event_notifier(iohandler_ctx, e, handler, NULL, NULL); } diff --git a/util/qemu-coroutine-io.c b/util/qemu-coroutine-io.c index d791932d63..364f4d5abf 100644 --- a/util/qemu-coroutine-io.c +++ b/util/qemu-coroutine-io.c @@ -74,8 +74,7 @@ typedef struct { static void fd_coroutine_enter(void *opaque) { FDYieldUntilData *data = opaque; - aio_set_fd_handler(data->ctx, data->fd, false, - NULL, NULL, NULL, NULL, NULL); + aio_set_fd_handler(data->ctx, data->fd, NULL, NULL, NULL, NULL, NULL); qemu_coroutine_enter(data->co); } @@ -87,7 +86,7 @@ void coroutine_fn yield_until_fd_readable(int fd) data.ctx = qemu_get_current_aio_context(); data.co = qemu_coroutine_self(); data.fd = fd; - aio_set_fd_handler( - data.ctx, fd, false, fd_coroutine_enter, NULL, NULL, NULL, &data); + aio_set_fd_handler(data.ctx, fd, fd_coroutine_enter, NULL, NULL, NULL, + &data); qemu_coroutine_yield(); } diff --git a/util/vhost-user-server.c b/util/vhost-user-server.c index a12b2d1bba..cd17fb5326 100644 --- a/util/vhost-user-server.c +++ b/util/vhost-user-server.c @@ -278,7 +278,7 @@ set_watch(VuDev *vu_dev, int fd, int vu_evt, vu_fd_watch->fd = fd; vu_fd_watch->cb = cb; qemu_socket_set_nonblock(fd); - aio_set_fd_handler(server->ioc->ctx, fd, false, kick_handler, + aio_set_fd_handler(server->ioc->ctx, fd, kick_handler, NULL, NULL, NULL, vu_fd_watch); vu_fd_watch->vu_dev = vu_dev; vu_fd_watch->pvt = pvt; @@ -299,8 +299,7 @@ static void remove_watch(VuDev *vu_dev, int fd) if (!vu_fd_watch) { return; } - aio_set_fd_handler(server->ioc->ctx, fd, false, - NULL, NULL, NULL, NULL, NULL); + aio_set_fd_handler(server->ioc->ctx, fd, NULL, NULL, NULL, NULL, NULL); QTAILQ_REMOVE(&server->vu_fd_watches, vu_fd_watch, next); g_free(vu_fd_watch); @@ -362,7 +361,7 @@ void vhost_user_server_stop(VuServer *server) VuFdWatch *vu_fd_watch; QTAILQ_FOREACH(vu_fd_watch, &server->vu_fd_watches, next) { - aio_set_fd_handler(server->ctx, vu_fd_watch->fd, false, + aio_set_fd_handler(server->ctx, vu_fd_watch->fd, NULL, NULL, NULL, NULL, vu_fd_watch); } @@ -403,7 +402,7 @@ void vhost_user_server_attach_aio_context(VuServer *server, AioContext *ctx) qio_channel_attach_aio_context(server->ioc, ctx); QTAILQ_FOREACH(vu_fd_watch, &server->vu_fd_watches, next) { - aio_set_fd_handler(ctx, vu_fd_watch->fd, false, kick_handler, NULL, + aio_set_fd_handler(ctx, vu_fd_watch->fd, kick_handler, NULL, NULL, NULL, vu_fd_watch); } @@ -417,7 +416,7 @@ void vhost_user_server_detach_aio_context(VuServer *server) VuFdWatch *vu_fd_watch; QTAILQ_FOREACH(vu_fd_watch, &server->vu_fd_watches, next) { - aio_set_fd_handler(server->ctx, vu_fd_watch->fd, false, + aio_set_fd_handler(server->ctx, vu_fd_watch->fd, NULL, NULL, NULL, NULL, vu_fd_watch); } diff --git a/tests/unit/meson.build b/tests/unit/meson.build index 3bc78d8660..b33298a444 100644 --- a/tests/unit/meson.build +++ b/tests/unit/meson.build @@ -122,9 +122,6 @@ if have_block if nettle.found() or gcrypt.found() tests += {'test-crypto-pbkdf': [io]} endif - if config_host_data.get('CONFIG_EPOLL_CREATE1') - tests += {'test-fdmon-epoll': [testblock]} - endif endif if have_system