[{"id":3675413,"web_url":"http://patchwork.ozlabs.org/comment/3675413/","msgid":"<adfegWEjLcGmDTPi@fedora>","list_archive_url":null,"date":"2026-04-09T17:15:28","subject":"Re: [PATCH 08/14] migration: Make qemu_savevm_query_pending()\n available anytime","submitter":{"id":89058,"url":"http://patchwork.ozlabs.org/api/people/89058/","name":"Juraj Marcin","email":"jmarcin@redhat.com"},"content":"On 2026-04-08 12:55, Peter Xu wrote:\n> After qemu_savevm_query_pending() be exposed to more code paths, it can be\n> used at very early stage when migration started and this may expose some\n> race conditions that we don't use to have.  This patch make it prepared\n> for such use cases so this API is fine to be used almost anytime.\n> \n> What matters here is, querying pending for each module normally depends on\n> save_setup() being run first, otherwise modules may not be ready for the\n> query request.\n> \n> Consider an early cancellation of migration after SETUP status but before\n> invocations of save_setup() hooks, source QEMU may fall into CANCELLING\n> stage directly from SETUP (not ACTIVE, which is the normal use case), in\n> which case save_setup() may not have been invoked and modules are not\n> ready.  However qemu_savevm_query_pending() may still be used in QMP\n> commands like query-migrate and causing crashes.\n> \n> Guard such use case by introducing a boolean reflecting the availability of\n> vmstate save handlers on correct completions of save_setup()s.  So far,\n> only protect qemu_savevm_query_pending() with it.  Logically other hooks\n> face similar concern, but most of them shouldn't be reachable from random\n> code path except migration thread so it should be fine.\n> \n> Signed-off-by: Peter Xu <peterx@redhat.com>\n> ---\n>  migration/migration.h |  8 ++++++++\n>  migration/savevm.h    |  2 +-\n>  migration/migration.c |  2 +-\n>  migration/savevm.c    | 37 +++++++++++++++++++++++++++++++++----\n>  4 files changed, 43 insertions(+), 6 deletions(-)\n> \n> diff --git a/migration/migration.h b/migration/migration.h\n> index b6888daced..e504df6915 100644\n> --- a/migration/migration.h\n> +++ b/migration/migration.h\n> @@ -522,6 +522,14 @@ struct MigrationState {\n>       * anything as input.\n>       */\n>      bool has_block_bitmap_mapping;\n> +\n> +    /*\n> +     * This boolean reflects if the vmstate handlers have been properly\n> +     * setup on source side.  It is set after vmstate save_setup() hooks\n> +     * are successfully invoked, and cleared after save_cleanup()s.  It\n> +     * reflects a general availability of vmstate hooks on the source side.\n> +     */\n> +    bool save_setup_ready;\n>  };\n>  \n>  void migrate_set_state(MigrationStatus *state, MigrationStatus old_state,\n> diff --git a/migration/savevm.h b/migration/savevm.h\n> index 96fdf96d4e..04ed09cec2 100644\n> --- a/migration/savevm.h\n> +++ b/migration/savevm.h\n> @@ -42,7 +42,7 @@ int qemu_savevm_state_resume_prepare(MigrationState *s);\n>  void qemu_savevm_send_header(QEMUFile *f);\n>  void qemu_savevm_state_header(QEMUFile *f);\n>  int qemu_savevm_state_iterate(QEMUFile *f, bool postcopy);\n> -void qemu_savevm_state_cleanup(void);\n> +void qemu_savevm_state_cleanup(MigrationState *s);\n>  void qemu_savevm_state_complete_postcopy(QEMUFile *f);\n>  int qemu_savevm_state_complete_precopy(MigrationState *s);\n>  void qemu_savevm_query_pending(MigPendingData *pending, bool exact);\n> diff --git a/migration/migration.c b/migration/migration.c\n> index bb17bd0e68..a9ee3360e1 100644\n> --- a/migration/migration.c\n> +++ b/migration/migration.c\n> @@ -1283,7 +1283,7 @@ static void migration_cleanup(MigrationState *s)\n>      g_free(s->hostname);\n>      s->hostname = NULL;\n>  \n> -    qemu_savevm_state_cleanup();\n> +    qemu_savevm_state_cleanup(s);\n>      cpr_state_close();\n>      cpr_transfer_source_destroy(s);\n>  \n> diff --git a/migration/savevm.c b/migration/savevm.c\n> index b75c311a95..1d3fce45b9 100644\n> --- a/migration/savevm.c\n> +++ b/migration/savevm.c\n> @@ -1387,7 +1387,8 @@ int qemu_savevm_state_non_iterable_early(QEMUFile *f,\n>      return 0;\n>  }\n>  \n> -static int qemu_savevm_state_setup(QEMUFile *f, Error **errp)\n> +static int qemu_savevm_state_setup(MigrationState *s, QEMUFile *f,\n> +                                   Error **errp)\n>  {\n>      SaveStateEntry *se;\n>      int ret;\n> @@ -1409,6 +1410,13 @@ static int qemu_savevm_state_setup(QEMUFile *f, Error **errp)\n>          }\n>      }\n>  \n> +    /*\n> +     * Logically, it should be paired with any hook being used who needs to\n> +     * load_acquire() the flag first.  So far, only save_query_pending()\n> +     * uses it.\n> +     */\n> +    qatomic_store_release(&s->save_setup_ready, true);\n\nWhat other savevm functions would benefit from this? Would it make sense\nto include them in this patch/series?\n\n> +\n>      return 0;\n>  }\n>  \n> @@ -1429,7 +1437,7 @@ int qemu_savevm_state_do_setup(QEMUFile *f, Error **errp)\n>          return ret;\n>      }\n>  \n> -    ret = qemu_savevm_state_setup(f, errp);\n> +    ret = qemu_savevm_state_setup(ms, f, errp);\n>      if (ret) {\n>          return ret;\n>      }\n> @@ -1764,10 +1772,23 @@ int qemu_savevm_state_complete_precopy(MigrationState *s)\n>  \n>  void qemu_savevm_query_pending(MigPendingData *pending, bool exact)\n>  {\n> +    MigrationState *s = migrate_get_current();\n>      SaveStateEntry *se;\n>  \n>      memset(pending, 0, sizeof(*pending));\n>  \n> +    /*\n> +     * This API can be invoked very early before SETUP is properly done, in\n> +     * that case don't invoke module queries because they're not ready.\n> +     * Just report all zeros.\n> +     *\n> +     * This is paired with save_setup_ready updates on save_setup() and\n> +     * save_cleanup().\n> +     */\n> +    if (!s || !qatomic_load_acquire(&s->save_setup_ready)) {\n> +        return;\n> +    }\n> +\n>      QTAILQ_FOREACH(se, &savevm_state.handlers, entry) {\n>          if (!se->ops || !se->ops->save_query_pending) {\n>              continue;\n> @@ -1786,7 +1807,7 @@ void qemu_savevm_query_pending(MigPendingData *pending, bool exact)\n>                                      pending->postcopy_bytes);\n>  }\n>  \n> -void qemu_savevm_state_cleanup(void)\n> +void qemu_savevm_state_cleanup(MigrationState *s)\n>  {\n>      SaveStateEntry *se;\n>      Error *local_err = NULL;\n> @@ -1795,6 +1816,14 @@ void qemu_savevm_state_cleanup(void)\n>          error_report_err(local_err);\n>      }\n>  \n> +    s->save_setup_ready = false;\n> +    /*\n> +     * Make sure we clear the flag before invoking save_cleanup(), so any\n> +     * racy QMP query-migrate won't try to invoke any save hooks.  Just use\n> +     * an explicit barrier to be simple.\n> +     */\n> +    smp_mb();\n> +\n>      trace_savevm_state_cleanup();\n>      QTAILQ_FOREACH(se, &savevm_state.handlers, entry) {\n>          if (se->ops && se->ops->save_cleanup) {\n> @@ -1841,7 +1870,7 @@ static int qemu_savevm_state(QEMUFile *f, Error **errp)\n>          error_setg_errno(errp, -ret, \"Error while writing VM state\");\n>      }\n>  cleanup:\n> -    qemu_savevm_state_cleanup();\n> +    qemu_savevm_state_cleanup(ms);\n>  \n>      if (ret != 0) {\n>          status = MIGRATION_STATUS_FAILED;\n> -- \n> 2.53.0\n>","headers":{"Return-Path":"<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>","X-Original-To":"incoming@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=aoPYI2+2;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=google header.b=rbK/NlRS;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org\n (client-ip=209.51.188.17; helo=lists.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)"],"Received":["from lists.gnu.org (lists1p.gnu.org [209.51.188.17])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fs6661D4Wz1xy1\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 10 Apr 2026 03:16:14 +1000 (AEST)","from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1wAsyr-0004x3-K3; Thu, 09 Apr 2026 13:15:50 -0400","from eggs.gnu.org ([2001:470:142:3::10])\n by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <jmarcin@redhat.com>)\n id 1wAsyl-0004sA-4J\n for qemu-devel@nongnu.org; Thu, 09 Apr 2026 13:15:44 -0400","from us-smtp-delivery-124.mimecast.com ([170.10.133.124])\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <jmarcin@redhat.com>)\n id 1wAsyh-0000tA-Ny\n for qemu-devel@nongnu.org; Thu, 09 Apr 2026 13:15:42 -0400","from mail-wr1-f69.google.com (mail-wr1-f69.google.com\n [209.85.221.69]) by relay.mimecast.com with ESMTP with STARTTLS\n (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n us-mta-260--tRaIXeHOW-_g1u-m0B0Pw-1; Thu, 09 Apr 2026 13:15:33 -0400","by mail-wr1-f69.google.com with SMTP id\n ffacd0b85a97d-43cff5bc312so954524f8f.1\n for <qemu-devel@nongnu.org>; Thu, 09 Apr 2026 10:15:32 -0700 (PDT)","from fedora (nat-88-212-17-233.antik.sk. [88.212.17.233])\n by smtp.gmail.com with ESMTPSA id\n ffacd0b85a97d-43d63e50044sm230785f8f.25.2026.04.09.10.15.29\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Thu, 09 Apr 2026 10:15:30 -0700 (PDT)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1775754934;\n h=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n to:to:cc:cc:mime-version:mime-version:content-type:content-type:\n in-reply-to:in-reply-to:references:references;\n bh=4WI70onklytO/0GFk7u4Ty3r38FWSYIgqh6nVMSPGI0=;\n b=aoPYI2+23RUkxcWJTgcVDsrWeFgBbv4JukH8CATat39lNF0mUHI5/Xu5/dNXoUuU/U49pN\n FlC1QoqpR4XEmrZUiGYZXxichWbGrj/CoI6HPoP/3y16NskoMl4oNQ2csmv7a12HE3PHzJ\n YRjjKpCBeCIduX21EIsARxTyWubOdKk=","v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=redhat.com; s=google; t=1775754932; x=1776359732; darn=nongnu.org;\n h=in-reply-to:content-disposition:mime-version:references:message-id\n :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to;\n bh=4WI70onklytO/0GFk7u4Ty3r38FWSYIgqh6nVMSPGI0=;\n b=rbK/NlRSbSkpj2UgpygJ+IXCbsHIYRp6OXQ/QinsN0/X8g/3XzFaHXlSaKAUnazNMn\n skC8OvtJhERToBJvYuYonhR9Z1rm5lX9WffgE57YxHuLroZYcUwGEABnaNdRE3diLmVn\n ugIpqQET9BoYfnykDrjItrpijKUqufrDYzTcGGJBo6g+DUciN3K/eUrmhB3oU3RytRM7\n N0subiPLIgPvR3GhXL51hbmqloqqb5pphNe/hcOnRGMzXb7nd6nqPMsBSvp6u4hKMwy0\n nWtKvAJxBw231ASxiJd35o/EsvqYeZzPH+ugHHqlfJhqnyPxD0Ia/0yyAcnqg6aRNCMs\n TFvQ=="],"X-MC-Unique":"-tRaIXeHOW-_g1u-m0B0Pw-1","X-Mimecast-MFC-AGG-ID":"-tRaIXeHOW-_g1u-m0B0Pw_1775754932","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1775754932; x=1776359732;\n h=in-reply-to:content-disposition:mime-version:references:message-id\n :subject:cc:to:from:date:x-gm-gg:x-gm-message-state:from:to:cc\n :subject:date:message-id:reply-to;\n bh=4WI70onklytO/0GFk7u4Ty3r38FWSYIgqh6nVMSPGI0=;\n b=pPrPc84pxtHr/a0ixyXSgE2wtP/HmE1Iixo6KK+Y8oBIJOM506or9TC5jEcYJxPZDK\n vMJSc7yDl4Lx/CP3++9KtAm/xSgqEWXkBv00LQxZBNpgIwSu9e0ouQnpk9u9xl5FGokg\n 16Kh/0IVMmWvyb7XbXlH9zjErWeTLQZjRB+Q+c+SYS5JRCWvYmYLDlS12aziAaMA9m1C\n p1X92fKtK26DS6b7myvlxBFB7NRh4VFf+VdEqV50ryeTIic1fjtM1wN0g4PO6cThdihb\n YMPDNZXPtT/UeYtw4zRaV12PuXgI6wDPSBZP6eRfq3GzzHA3WztWm3FU+QeuI5mECDZt\n czzw==","X-Gm-Message-State":"AOJu0Yx/zoiGAncWCGd9VEDNdcE97o41FmZzxfpZ3SIAN+XBH5VNZ7zI\n vYXeOc4y2ySgBr1zpmu+TLodAEUjF6pnx91YtP4Qlc7xwLjTXxZOCAIftLyQH6E2PdOQo59rjXU\n ToxTmMaiyR9s9VkSvUmOk89UdSMnsU1aCiwYir53nvdSinQKPxGX+mOwW","X-Gm-Gg":"AeBDieu5QGpA325rFsTG/31B+f+5k8FjjBK8x0XHrcBOGp8COtgE80TVx7VSKj5BJ8K\n tLZTKLLrbVzRE/ih0cHa4esOGvmwBGXSmO55GJXU2gTrfroJ3F7ai7HF1/Y8nRX8M66ZukVilIU\n FiicCVmQgwfDX1AaUxfBcx70EL21FSpFE7i33NOQU3KaNpg9r6efLSfhof6Oxfq6n63L0/NvsbN\n PfzBK2B/TEwUdiPdh+l456SsVl0Dm48v7SUtjAk1I7McFoGNIt5OICDZdz8A45PN1yj3EYXRFo+\n jeLv9/UoOd7CHgCiMFEW9lSA0nYK/7BeAGbV2i2toQxHBJ/+KihSst2Yhvb7iATCkEuZgX/7vRN\n puDt2K1zRguCFGswqOQaREa9SDHhFoVYxoGWGP1A=","X-Received":["by 2002:a05:6000:2388:b0:43d:b99:bdc4 with SMTP id\n ffacd0b85a97d-43d292d32d9mr36944541f8f.30.1775754931488;\n Thu, 09 Apr 2026 10:15:31 -0700 (PDT)","by 2002:a05:6000:2388:b0:43d:b99:bdc4 with SMTP id\n ffacd0b85a97d-43d292d32d9mr36944474f8f.30.1775754930976;\n Thu, 09 Apr 2026 10:15:30 -0700 (PDT)"],"Date":"Thu, 9 Apr 2026 19:15:28 +0200","From":"Juraj Marcin <jmarcin@redhat.com>","To":"Peter Xu <peterx@redhat.com>","Cc":"qemu-devel@nongnu.org,\n  \"Maciej S . Szmigiero\" <mail@maciej.szmigiero.name>, Daniel P\n\t=?utf-8?b?LiBCZXJyYW5nw6k=?= <berrange@redhat.com>,\n  Zhiyi Guo <zhguo@redhat.com>, Prasad Pandit <ppandit@redhat.com>,\n  Avihai Horon <avihaih@nvidia.com>, Kirti Wankhede <kwankhede@nvidia.com>,\n\t=?utf-8?q?C=C3=A9dric?= Le Goater <clg@redhat.com>,\n Fabiano Rosas <farosas@suse.de>,  Joao Martins <joao.m.martins@oracle.com>,\n Markus Armbruster <armbru@redhat.com>, Alex Williamson <alex@shazbot.org>","Subject":"Re: [PATCH 08/14] migration: Make qemu_savevm_query_pending()\n available anytime","Message-ID":"<adfegWEjLcGmDTPi@fedora>","References":"<20260408165559.157108-1-peterx@redhat.com>\n <20260408165559.157108-9-peterx@redhat.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=us-ascii","Content-Disposition":"inline","In-Reply-To":"<20260408165559.157108-9-peterx@redhat.com>","Received-SPF":"pass client-ip=170.10.133.124; envelope-from=jmarcin@redhat.com;\n helo=us-smtp-delivery-124.mimecast.com","X-Spam_score_int":"-25","X-Spam_score":"-2.6","X-Spam_bar":"--","X-Spam_report":"(-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.54,\n DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1,\n RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=0.001,\n RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001,\n SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham 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 <qemu-devel.nongnu.org>","List-Unsubscribe":"<https://lists.nongnu.org/mailman/options/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>","List-Archive":"<https://lists.nongnu.org/archive/html/qemu-devel>","List-Post":"<mailto:qemu-devel@nongnu.org>","List-Help":"<mailto:qemu-devel-request@nongnu.org?subject=help>","List-Subscribe":"<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=subscribe>","Errors-To":"qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org","Sender":"qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org"}}]