Virtuozzo QEMU development (svt-core@virtuozzo.com)
 help / color / mirror / Atom feed
From: no-reply@sashiko.virtuozzo.com
To: svt-core@virtuozzo.com,
	 Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
Cc: andrey.drobyshev@virtuozzo.com, den@openvz.org
Subject: Re: [PATCH hci-dev v5 1/2] vfio/migration: stop a device left running after a guest shutdown #VSTOR-153976
Date: Mon, 9 Nov 2026 19:15:04 +0000	[thread overview]
Message-ID: <010701a1c1bc4764-0cc8f804-2d7e-4f03-a926-97407c81d235-000000@eu-central-1.amazonses.com> (raw)
In-Reply-To: <20261109190342.200293-2-andrey.drobyshev@virtuozzo.com>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] vfio/migration: stop helper misses RUNNING device left in a PAUSED VM
- [Low] vfio: stop_after_shutdown() stops RUNNING devices one by one without a P2P round
--

commit 011d0ac85a859eefe6fc0507fe391eb5b7768f9c
Author: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>

vfio/migration: stop a device left running after a guest shutdown

This patch adds vfio_migration_stop_after_shutdown(). It stops a VFIO
device that is still in RUNNING_P2P, or in RUNNING while the VM is in
SHUTDOWN. The helper is called from a new shutdown notifier and from
vfio_save_setup().

> diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
> --- a/hw/vfio/migration.c
> +++ b/hw/vfio/migration.c

[ ... ]

> +/*
> + * Stop a device that a guest shutdown left running, before it is closed or
> + * saved. Only that leaves a device in RUNNING_P2P, or in RUNNING while the
> + * VM is in SHUTDOWN. The P2P round of the VM stop has already run, so the
> + * devices are stopped one by one.
> + */
> +static int vfio_migration_stop_after_shutdown(VFIODevice *vbasedev,
> +                                              Error **errp)
> +{
> +    VFIOMigration *migration = vbasedev->migration;
> +
> +    if (migration->device_state != VFIO_DEVICE_STATE_RUNNING_P2P &&
> +        !(runstate_check(RUN_STATE_SHUTDOWN) &&
> +          migration->device_state == VFIO_DEVICE_STATE_RUNNING)) {
> +        return 0;
> +    }
> +
> +    return vfio_migration_set_state(vbasedev, VFIO_DEVICE_STATE_STOP,
> +                                    VFIO_DEVICE_STATE_RUNNING, errp);
> +}

[Severity: Medium]
Can a RUNNING device be left behind in a PAUSED or PRELAUNCH VM here?
The helper stops a RUNNING device only when the run state is exactly
RUN_STATE_SHUTDOWN.

One path that seems to reach this state:

    VM is PAUSED, VFIO device is in STOP
    migration_stop_vm()
      vm_stop_force_state(RUN_STATE_FINISH_MIGRATE)
        (VM not live: runstate_set() only, no vmstate-change
         notification, device stays in STOP)
    migration fails or is cancelled
    migration_cleanup()
      migration_call_notifiers(MIG_EVENT_PRECOPY_FAILED)
        vfio_migration_state_notifier()
          vfio_migration_set_state_or_reset(RUNNING)
    migration_iteration_finish()
      if (runstate_is_live(s->vm_old_state)) {
          ...
      } else {
          if (runstate_check(RUN_STATE_FINISH_MIGRATE)) {
              runstate_set(s->vm_old_state);
          }
      }

For a non-live old state, vm_start() is not called. The device ends up
RUNNING in a PAUSED VM.

On a later quit, vfio_migration_shutdown_notifier() calls
vfio_migration_stop_after_shutdown(). The device state is RUNNING, not
RUNNING_P2P, and the run state is PAUSED, not SHUTDOWN. So the helper
returns 0 and the device is closed running.

A retried migration reaches vfio_save_setup(), which calls the same
helper and also returns 0.

The commit message says "Today only a failed migration of such a VM leaves
a device running there", and the helper comment says "or in RUNNING while
the VM is in SHUTDOWN". Both seem to understate this case, because the
same failed-migration path also leaves a RUNNING device in PAUSED and
PRELAUNCH VMs.

The follow-up patch "vfio/migration: don't stop the device on guest
shutdown" only adds an early return in vfio_vmstate_change(). It doesn't
change the PRECOPY_FAILED handler or the run-state check in this helper.

Should the helper cover this case, or should the PRECOPY_FAILED handler
avoid setting RUNNING when the VM is not running?

[Severity: Low]
Is the comment "The P2P round of the VM stop has already run, so the
devices are stopped one by one" accurate for the RUNNING branch?

A device in plain RUNNING in RUN_STATE_SHUTDOWN did not go through
vfio_vmstate_change_prepare(). It is sent straight to STOP with no
all-device RUNNING_P2P round first.

The path to that state is a failed migration of a -no-shutdown VM:

    vfio_migration_state_notifier()
      /* MIG_EVENT_PRECOPY_FAILED */
      vfio_migration_set_state_or_reset(RUNNING)

This moves every device to plain RUNNING while the VM stays in SHUTDOWN.

A later quit or a new save then reaches
vfio_migration_stop_after_shutdown() for each device in turn. With two or
more P2P-capable devices, one device can go to STOP while a peer is still
RUNNING and able to DMA to it.

I haven't shown that this causes a concrete failure. The comment is only
correct for devices found in RUNNING_P2P. The follow-up patch makes
RUNNING_P2P the common case, but it leaves the RUNNING branch and this
comment unchanged.

[ ... ]

> +static void vfio_migration_shutdown_notifier(Notifier *notifier, void *data)
> +{
> +    VFIOMigration *migration = container_of(notifier, VFIOMigration,
> +                                            shutdown);
> +    Error *local_err = NULL;
> +
> +    /* QEMU is quitting: a device left running must be stopped first */
> +    if (qemu_shutdown_action_is_pause()) {
> +        return;
> +    }
> +
> +    if (vfio_migration_stop_after_shutdown(migration->vbasedev, &local_err)) {
> +        error_report_err(local_err);
> +    }
> +}

[Severity: Low]
Each device is stopped individually by its own notifier, with no
coordination between devices, and a failure is only logged with
error_report_err().

Could a device that fails to stop here still be closed running?

[ ... ]

Please let me know if I have misread any of these paths.

-- 
Sashiko AI review · https://sashiko.vzint.dev/#/patchset/20261109190342.200293-1-andrey.drobyshev@virtuozzo.com?part=1

  reply	other threads:[~2026-11-09 19:15 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-09 19:03 [PATCH hci-dev v5 0/2] vfio/migration: don't stop the device on " Andrey Drobyshev
2026-11-09 19:03 ` [PATCH hci-dev v5 1/2] vfio/migration: stop a device left running after a " Andrey Drobyshev
2026-11-09 19:15   ` no-reply [this message]
2026-11-09 19:03 ` [PATCH hci-dev v5 2/2] vfio/migration: don't stop the device on " Andrey Drobyshev
2026-11-09 19:15   ` 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=010701a1c1bc4764-0cc8f804-2d7e-4f03-a926-97407c81d235-000000@eu-central-1.amazonses.com \
    --to=no-reply@sashiko.virtuozzo.com \
    --cc=andrey.drobyshev@virtuozzo.com \
    --cc=den@openvz.org \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox