From: no-reply@sashiko.virtuozzo.com
To: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>,
svt-core@virtuozzo.com
Subject: Re: [PATCH QEMU HCI-8.1 v4 19/31] migration: Fix crash on second migration when cancel early
Date: Tue, 20 Oct 2026 16:52:56 +0000 [thread overview]
Message-ID: <010701a15a3af796-43ae3812-134a-4633-98ce-cbbdb2112f98-000000@eu-central-1.amazonses.com> (raw)
In-Reply-To: <20261020-vfio_v1-v4-19-83a5668230e5@virtuozzo.com>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] migration: cancel in cpr-transfer HUP window sends FAILED without SETUP, can abort via VFIO notifier
- [Medium] migration: migration_cancel() asserts on mode that migrate-set-parameters can change
- [Low] migration: qmp_migrate_finish_cb() comment refers to a nonexistent redundant destroy
--
commit e43a55e4327f60b3f762f7e2bead9f8ce8624d43
Author: Peter Xu <peterx@redhat.com>
migration: Fix crash on second migration when cancel early
This commit makes migration_cancel() call migration_cleanup() when the
cpr-transfer HUP gsource is still pending. It also detaches hup_source
at entry to qmp_migrate_finish_cb(), and adds some assertions. This
fixes a crash when a cancelled early-setup migration is retried.
Link: https://lore.kernel.org/r/20260417184742.293061-1-marcandre.lureau@redhat.com
Link: https://lore.kernel.org/r/20260421175820.302795-1-peterx@redhat.com
> diff --git a/migration/migration.c b/migration/migration.c
> index b7db5c94b0d9..3732751e66c7 100644
> --- a/migration/migration.c
> +++ b/migration/migration.c
[ ... ]
> @@ -1661,14 +1661,19 @@ void migration_cancel(void)
> }
>
> /*
> - * If qmp_migrate_finish has not been called, then there is no path that
> - * will complete the cancellation. Do it now.
> + * This is cpr-transfer specific processing.
> + *
> + * If this is true, it means cpr-transfer migration is waiting for the
> + * destination to send HUP event on CPR channel to continue the next
> + * phase. If so, do the cleanup proactively to avoid get stuck in
> + * CANCELLING state.
> */
> - if (setup && !s->to_dst_file) {
> - migrate_set_state(&s->state, MIGRATION_STATUS_CANCELLING,
> - MIGRATION_STATUS_CANCELLED);
> - cpr_state_close();
> - cpr_transfer_source_destroy(s);
> + if (cpr_transfer_source_active(s)) {
> + assert(migrate_mode() == MIG_MODE_CPR_TRANSFER);
> + assert(setup && !s->to_dst_file);
> + migration_cleanup(s);
> + /* Now all things should have been released */
> + assert(!cpr_transfer_source_active(s));
> }
> }
[Severity: High]
Can this migration_cleanup() call abort QEMU through a VFIO notifier?
In the cpr-transfer HUP-wait window, qmp_migrate() has only called
cpr_transfer_add_hup_watch() and returned. migration_connect() has not
run, so migration_call_notifiers(MIG_EVENT_PRECOPY_SETUP) has not been
delivered. The SETUP handler vfio_cpr_pci_notifier(), which disables the
MSI/INTx irqfds, has therefore not run.
If migrate_cancel arrives in this window, migration_cancel() calls
migration_cleanup(), which ends with:
type = migration_has_failed(s) ? MIG_EVENT_PRECOPY_FAILED :
MIG_EVENT_PRECOPY_DONE;
migration_call_notifiers(type, NULL);
For MIG_EVENT_PRECOPY_FAILED, vfio_cpr_pci_notifier() calls
vfio_cpr_set_msi_virq(vdev, errp, true). That re-adds irqfds which were
never removed. If KVM_IRQFD assign rejects the duplicate, the notifier
returns non-zero. I have not verified the kernel behaviour for a
duplicate assign.
migration_call_notifiers() then reaches:
ret = notifier->notify(notifier, &e, errp);
if (ret) {
assert(type == MIG_EVENT_PRECOPY_SETUP);
That assert would fire for a FAILED event and abort the running source
QEMU. The old code in this path sent no notifier events.
Is it intended that FAILED is delivered here without a preceding SETUP,
and is vfio_cpr_pci_notifier() expected to tolerate that? The commit
message does not mention this side effect.
[Severity: Medium]
Can assert(migrate_mode() == MIG_MODE_CPR_TRANSFER) fire here?
migrate_mode() reads the live s->parameters.mode. migrate_params_apply()
applies has_mode with no check for a running migration:
if (params->has_mode) {
s->parameters.mode = params->mode;
}
qmp_migrate() samples the mode only once, when it calls
cpr_transfer_add_hup_watch(), and does not record it. Consider this
sequence:
qmp_migrate() /* cpr-transfer, hup_source set */
migrate-set-parameters mode=normal
migrate_cancel (or migration_shutdown() at exit)
migration_cancel()
cpr_transfer_source_active(s) /* true */
assert(migrate_mode() == MIG_MODE_CPR_TRANSFER) /* fails */
That would abort QEMU in a case where the old code just cancelled and
cleaned up. The cleanup itself does not depend on the mode. Is this
assertion needed?
> @@ -2266,11 +2271,22 @@ static gboolean qmp_migrate_finish_cb(QIOChannel *channel,
> void *opaque)
> {
> MigrationAddress *addr = opaque;
> + MigrationState *s = migrate_get_current();
> +
> + /*
> + * Detach and release the GSource right after use. We rely on this to
> + * detect this small cpr-transfer window of "waiting for HUP event".
> + */
> + cpr_transfer_source_destroy(s);
>
> qmp_migrate_finish(addr, NULL);
>
> cpr_state_close();
> - cpr_transfer_source_destroy(migrate_get_current());
> +
> + /*
> + * This is redundant as we do cpr_transfer_source_destroy() at the
> + * entry, but it's benign; glib will just skip the detach.
> + */
> return G_SOURCE_REMOVE;
> }
[Severity: Low]
This isn't a bug, but the new comment before return G_SOURCE_REMOVE says
"This is redundant as we do cpr_transfer_source_destroy() at the entry".
No second cpr_transfer_source_destroy() call remains in
qmp_migrate_finish_cb(), because the patch removes the trailing one.
The comment seems to describe code that is not present in this backport.
Could it be reworded or dropped?
--
Sashiko AI review · https://sashiko.vzint.dev/#/patchset/20261020-vfio_v1-v4-0-83a5668230e5@virtuozzo.com?part=19
next prev parent reply other threads:[~2026-10-20 16:53 UTC|newest]
Thread overview: 63+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-20 16:30 [PATCH QEMU HCI-8.1 v4 00/31] vfio: support qemu-update with passed through GPU's and vGPU's #VSTOR-103860 Andrey Drobyshev
2026-10-20 16:30 ` [PATCH QEMU HCI-8.1 v4 01/31] VZ: migration/cpr-exec: fix Error leak in preserve_ram() Andrey Drobyshev
2026-10-20 16:34 ` no-reply
2026-10-20 16:30 ` [PATCH QEMU HCI-8.1 v4 02/31] migration/cpr-exec: restore RAM write access if exec fails Andrey Drobyshev
2026-10-20 16:34 ` no-reply
2026-10-20 16:30 ` [PATCH QEMU HCI-8.1 v4 03/31] vfio/region: create BAR dma-bufs with O_CLOEXEC Andrey Drobyshev
2026-10-20 16:35 ` no-reply
2026-10-20 16:30 ` [PATCH QEMU HCI-8.1 v4 04/31] migration/cpr-exec: require a file or exec migration URI Andrey Drobyshev
2026-10-20 16:37 ` no-reply
2026-10-20 16:30 ` [PATCH QEMU HCI-8.1 v4 05/31] migration: close the CPR state if the outgoing channel fails to open Andrey Drobyshev
2026-10-20 16:38 ` no-reply
2026-10-20 16:30 ` [PATCH QEMU HCI-8.1 v4 06/31] migration: Plug memory leaks after migrate_set_error() Andrey Drobyshev
2026-10-20 16:38 ` no-reply
2026-10-20 16:30 ` [PATCH QEMU HCI-8.1 v4 07/31] hw/vfio: Fix liveness check in vfio_connect_kvm_msi_virq() Andrey Drobyshev
2026-10-20 16:38 ` no-reply
2026-10-20 16:30 ` [PATCH QEMU HCI-8.1 v4 08/31] vfio/pci: Reject invalid MSI-X Table and PBA BIR values Andrey Drobyshev
2026-10-20 16:38 ` no-reply
2026-10-20 16:30 ` [PATCH QEMU HCI-8.1 v4 09/31] vfio/pci: Fix information leak in vfio_rom_read() Andrey Drobyshev
2026-10-20 16:39 ` no-reply
2026-10-20 16:30 ` [PATCH QEMU HCI-8.1 v4 10/31] vfio/pci: Initialize rom_read_failed in vfio_pci_load_rom() Andrey Drobyshev
2026-10-20 16:40 ` no-reply
2026-10-20 16:30 ` [PATCH QEMU HCI-8.1 v4 11/31] vfio/pci: Grow buffer in vfio_pci_host_match() Andrey Drobyshev
2026-10-20 16:39 ` no-reply
2026-10-20 16:30 ` [PATCH QEMU HCI-8.1 v4 12/31] q35: Fix migration of SMRAM state Andrey Drobyshev
2026-10-20 16:41 ` no-reply
2026-10-20 16:30 ` [PATCH QEMU HCI-8.1 v4 13/31] migration: ensure APIC is loaded prior to VFIO PCI devices Andrey Drobyshev
2026-10-20 16:40 ` no-reply
2026-10-20 16:30 ` [PATCH QEMU HCI-8.1 v4 14/31] migration: Fix regression of passing error_fatal into vmstate_load_state() Andrey Drobyshev
2026-10-20 16:43 ` no-reply
2026-10-20 16:30 ` [PATCH QEMU HCI-8.1 v4 15/31] migration: vmstate_save_state_v: fix double error_setg Andrey Drobyshev
2026-10-20 16:45 ` no-reply
2026-10-20 16:30 ` [PATCH QEMU HCI-8.1 v4 16/31] migration: yank: Move register instance earlier Andrey Drobyshev
2026-10-20 16:47 ` no-reply
2026-10-20 16:30 ` [PATCH QEMU HCI-8.1 v4 17/31] migration: Free cpr-transfer MigrationAddress along with gsource Andrey Drobyshev
2026-10-20 16:47 ` no-reply
2026-10-20 16:30 ` [PATCH QEMU HCI-8.1 v4 18/31] migration: Move CPR HUP watch to cpr-transfer.c Andrey Drobyshev
2026-10-20 16:48 ` no-reply
2026-10-20 16:30 ` [PATCH QEMU HCI-8.1 v4 19/31] migration: Fix crash on second migration when cancel early Andrey Drobyshev
2026-10-20 16:52 ` no-reply [this message]
2026-10-20 16:31 ` [PATCH QEMU HCI-8.1 v4 20/31] kvm: tolerate ioctls after kvm_close() Andrey Drobyshev
2026-10-20 16:52 ` no-reply
2026-10-20 16:31 ` [PATCH QEMU HCI-8.1 v4 21/31] kvm: fix coalesced MMIO flush racing with kvm_close() Andrey Drobyshev
2026-10-20 16:54 ` no-reply
2026-10-20 16:31 ` [PATCH QEMU HCI-8.1 v4 22/31] migration/cpr: add cpr_is_in_progress() Andrey Drobyshev
2026-10-20 16:54 ` no-reply
2026-10-20 16:31 ` [PATCH QEMU HCI-8.1 v4 23/31] vfio/migration: don't migrate device state during CPR Andrey Drobyshev
2026-10-20 17:00 ` no-reply
2026-10-20 16:31 ` [PATCH QEMU HCI-8.1 v4 24/31] vfio/listener: skip dirty page tracking " Andrey Drobyshev
2026-10-20 16:59 ` no-reply
2026-10-20 16:31 ` [PATCH QEMU HCI-8.1 v4 25/31] VZ: vfio/cpr: don't close KVM on cpr-exec Andrey Drobyshev
2026-10-20 17:01 ` no-reply
2026-10-20 16:31 ` [PATCH QEMU HCI-8.1 v4 26/31] VZ: migration/cpr-exec: abort cpr-exec if memory can't be preserved Andrey Drobyshev
2026-10-20 17:02 ` no-reply
2026-10-20 16:31 ` [PATCH QEMU HCI-8.1 v4 27/31] VZ: migration/cpr-exec: take the vhost-net devices back if exec fails Andrey Drobyshev
2026-10-20 17:03 ` no-reply
2026-10-20 16:31 ` [PATCH QEMU HCI-8.1 v4 28/31] VZ: migration/cpr-exec: don't exec if a vhost-net device can't be released Andrey Drobyshev
2026-10-20 17:03 ` no-reply
2026-10-20 16:31 ` [PATCH QEMU HCI-8.1 v4 29/31] VZ: vfio/region: preserve BAR mappings across cpr-exec #VSTOR-103860 Andrey Drobyshev
2026-10-20 17:08 ` no-reply
2026-10-20 16:31 ` [PATCH QEMU HCI-8.1 v4 30/31] VZ: migration/cpr-exec: allow cpr-exec with VFIO devices #VSTOR-103860 Andrey Drobyshev
2026-10-20 17:04 ` no-reply
2026-10-20 16:31 ` [PATCH QEMU HCI-8.1 v4 31/31] VZ: vfio/container: lift the CPR blocker for mdev " Andrey Drobyshev
2026-10-20 17:06 ` no-reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=010701a15a3af796-43ae3812-134a-4633-98ce-cbbdb2112f98-000000@eu-central-1.amazonses.com \
--to=no-reply@sashiko.virtuozzo.com \
--cc=andrey.drobyshev@virtuozzo.com \
--cc=svt-core@virtuozzo.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.