From mboxrd@z Thu Jan 1 00:00:00 1970 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 lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) (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 5D3E4FF885A for ; Tue, 5 May 2026 08:45:08 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wKBOL-0005E3-Tb; Tue, 05 May 2026 04:44:33 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wKBOH-0005DW-PE for qemu-devel@nongnu.org; Tue, 05 May 2026 04:44:29 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wKBOG-0004EC-8s for qemu-devel@nongnu.org; Tue, 05 May 2026 04:44:29 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1777970667; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type; bh=wMEfkeHNsX1m7cd1AfdWOazE57PbuGCY/o6IOEnGpuY=; b=DK8nuWirjUEaRpGSgdAxeYpdstUq4f/3n9ooCHMAQAUWpfD484fdEi8iGpXgZAiY/7qtpa MfjfpNl+c6w4ZHg4PST9qhbjA+QFCFclC7EaoTG8He4w4tSkIiO/M+QZlPcMZ9yh+1USK3 jRWTB+8DQydvuVnUKRC79ZW5sIu05XQ= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-251-vFCfClLqMO2IRvqJSs9xcA-1; Tue, 05 May 2026 04:44:25 -0400 X-MC-Unique: vFCfClLqMO2IRvqJSs9xcA-1 X-Mimecast-MFC-AGG-ID: vFCfClLqMO2IRvqJSs9xcA_1777970664 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 71649195605A; Tue, 5 May 2026 08:44:24 +0000 (UTC) Received: from blackfin.pond.sub.org (unknown [10.44.22.2]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 2EE43196B09E; Tue, 5 May 2026 08:44:23 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 9828521E6A01; Tue, 05 May 2026 10:44:21 +0200 (CEST) From: Markus Armbruster To: qemu-devel@nongnu.org, qemu-rust@nongnu.org, Paolo Bonzini , Kevin Wolf , Hanna Czenczek , Stefan Hajnoczi Subject: Can we make QMP commands in Rust always be coroutine safe? Date: Tue, 05 May 2026 10:44:21 +0200 Message-ID: <87tssm5jq2.fsf@pond.sub.org> User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 Content-Type: text/plain X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 Received-SPF: pass client-ip=170.10.129.124; envelope-from=armbru@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: 8 X-Spam_score: 0.8 X-Spam_bar: / X-Spam_report: (0.8 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.444, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_SBL_CSS=3.335, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org QMP commands that perform potentially blocking I/O can profit from running in a coroutine. Ideally, we'd run all commands in coroutine context: most of them don't care, a few profit. However, some existing commands may need fixing to run safely there. Since we don't know which ones do, running in couroutine context is opt-in. From docs/devel/qapi-code-gen.rst section "Commands": Member 'coroutine' tells the QMP dispatcher whether the command handler is safe to be run in a coroutine. It defaults to false. If it is true, the command handler is called from coroutine context and may yield while waiting for an external event (such as I/O completion) in order to avoid blocking the guest and other background operations. Coroutine safety can be hard to prove, similar to thread safety. Common pitfalls are: - The BQL isn't held across ``qemu_coroutine_yield()``, so operations that used to assume that they execute atomically may have to be more careful to protect against changes in the global state. - Nested event loops (``AIO_WAIT_WHILE()`` etc.) are problematic in coroutine context and can easily lead to deadlocks. They should be replaced by yielding and reentering the coroutine when the condition becomes false. Since the command handler may assume coroutine context, any callers other than the QMP dispatcher must also call it in coroutine context. In particular, HMP commands calling such a QMP command handler must be marked ``.coroutine = true`` in hmp-commands.hx. It is an error to specify both ``'coroutine': true`` and ``'allow-oob': true`` for a command. We don't currently have a use case for both together and without a use case, it's not entirely clear what the semantics should be. Can we make commands written in Rust always coroutine safe?