qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Avihai Horon <avihaih@nvidia.com>
To: <qemu-devel@nongnu.org>
Cc: "Alex Williamson" <alex.williamson@redhat.com>,
	"Cédric Le Goater" <clg@redhat.com>,
	"Juan Quintela" <quintela@redhat.com>,
	"Peter Xu" <peterx@redhat.com>,
	"Leonardo Bras" <leobras@redhat.com>,
	"Yanghang Liu" <yanghliu@redhat.com>,
	"Avihai Horon" <avihaih@nvidia.com>
Subject: [PATCH 6/6] vfio/migration: Block VFIO migration with background snapshot
Date: Mon, 28 Aug 2023 18:18:42 +0300	[thread overview]
Message-ID: <20230828151842.11303-7-avihaih@nvidia.com> (raw)
In-Reply-To: <20230828151842.11303-1-avihaih@nvidia.com>

Background snapshot allows creating a snapshot of the VM while it's
running and keeping it small by not including dirty RAM pages.

The way it works is by first stopping the VM, saving the non-iterable
devices' state and then starting the VM and saving the RAM while write
protecting it with UFFD. The resulting snapshot represents the VM state
at snapshot start.

VFIO migration is not compatible with background snapshot.
First of all, VFIO device state is not even saved in background snapshot
because only non-iterable device state is saved. But even if it was
saved, after starting the VM, a VFIO device could dirty pages without it
being detected by UFFD write protection. This would corrupt the
snapshot, as the RAM in it would not represent the RAM at snapshot
start.

To prevent this and to be explicit about supported features, block VFIO
migration with background snapshot: Fail setting background snapshot
capability if a VFIO device is present, and add a migration blocker if a
VFIO device is added when background snapshot capability is on.

Signed-off-by: Avihai Horon <avihaih@nvidia.com>
---
 include/hw/vfio/vfio-common.h |  2 ++
 migration/migration.h         |  1 +
 hw/vfio/common.c              | 42 +++++++++++++++++++++++++++++++++++
 hw/vfio/migration.c           |  6 +++++
 migration/options.c           |  7 ++++++
 migration/target.c            |  9 ++++++++
 6 files changed, 67 insertions(+)

diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index c0b58f2bb7..bb94f320f1 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -229,6 +229,8 @@ int vfio_block_multiple_devices_migration(VFIODevice *vbasedev, Error **errp);
 void vfio_unblock_multiple_devices_migration(void);
 int vfio_block_postcopy_migration(VFIODevice *vbasedev, Error **errp);
 void vfio_unblock_postcopy_migration(void);
+int vfio_block_background_snapshot(VFIODevice *vbasedev, Error **errp);
+void vfio_unblock_background_snapshot(void);
 bool vfio_viommu_preset(VFIODevice *vbasedev);
 int64_t vfio_mig_bytes_transferred(void);
 void vfio_reset_bytes_transferred(void);
diff --git a/migration/migration.h b/migration/migration.h
index 21a6423408..3077ed430b 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -516,6 +516,7 @@ void migration_populate_vfio_info(MigrationInfo *info);
 void migration_reset_vfio_bytes_transferred(void);
 bool migration_vfio_mig_active(void);
 void migration_vfio_unblock_postcopy_migration(void);
+void migration_vfio_unblock_background_snapshot(void);
 void postcopy_temp_page_reset(PostcopyTmpPage *tmp_page);
 
 #endif
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 7461194b2b..4f6bc40cc0 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -345,6 +345,7 @@ static int vfio_get_dirty_bitmap(VFIOContainer *container, uint64_t iova,
 
 static Error *multiple_devices_migration_blocker;
 static Error *postcopy_migration_blocker;
+static Error *background_snapshot_blocker;
 
 static unsigned int vfio_migratable_devices_num(void)
 {
@@ -470,6 +471,47 @@ void vfio_unblock_postcopy_migration(void)
     postcopy_migration_blocker = NULL;
 }
 
+int vfio_block_background_snapshot(VFIODevice *vbasedev, Error **errp)
+{
+    int ret;
+
+    if (!migrate_background_snapshot()) {
+        return 0;
+    }
+
+    if (vbasedev->enable_migration == ON_OFF_AUTO_ON) {
+        error_setg(errp,
+                   "VFIO migration is not compatible with background snapshot");
+        return -EINVAL;
+    }
+
+    if (background_snapshot_blocker) {
+        return 0;
+    }
+
+    error_setg(&background_snapshot_blocker,
+               "VFIO migration is not compatible with background snapshot");
+    ret = migrate_add_blocker(background_snapshot_blocker, errp);
+    if (ret < 0) {
+        error_free(background_snapshot_blocker);
+        background_snapshot_blocker = NULL;
+    }
+
+    return ret;
+}
+
+void vfio_unblock_background_snapshot(void)
+{
+    if (!background_snapshot_blocker ||
+        (vfio_migratable_devices_num() && migrate_background_snapshot())) {
+        return;
+    }
+
+    migrate_del_blocker(background_snapshot_blocker);
+    error_free(background_snapshot_blocker);
+    background_snapshot_blocker = NULL;
+}
+
 bool vfio_mig_active(void)
 {
     return vfio_migratable_devices_num();
diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
index 76406e9ae9..adf98ac8e3 100644
--- a/hw/vfio/migration.c
+++ b/hw/vfio/migration.c
@@ -857,6 +857,7 @@ static void vfio_migration_deinit(VFIODevice *vbasedev)
     vfio_migration_free(vbasedev);
     vfio_unblock_multiple_devices_migration();
     vfio_unblock_postcopy_migration();
+    vfio_unblock_background_snapshot();
 }
 
 static int vfio_block_migration(VFIODevice *vbasedev, Error *err, Error **errp)
@@ -945,6 +946,11 @@ bool vfio_migration_realize(VFIODevice *vbasedev, Error **errp)
         goto out_deinit;
     }
 
+    ret = vfio_block_background_snapshot(vbasedev, errp);
+    if (ret) {
+        goto out_deinit;
+    }
+
     if (vfio_viommu_preset(vbasedev)) {
         error_setg(&err, "%s: Migration is currently not supported "
                    "with vIOMMU enabled", vbasedev->name);
diff --git a/migration/options.c b/migration/options.c
index e201053563..2e13363de6 100644
--- a/migration/options.c
+++ b/migration/options.c
@@ -537,6 +537,12 @@ bool migrate_caps_check(bool *old_caps, bool *new_caps, Error **errp)
                 return false;
             }
         }
+
+        if (migration_vfio_mig_active()) {
+            error_setg(errp, "Background-snapshot is not compatible with VFIO "
+                             "migration");
+            return false;
+        }
     }
 
 #ifdef CONFIG_LINUX
@@ -625,6 +631,7 @@ bool migrate_caps_check(bool *old_caps, bool *new_caps, Error **errp)
 static void migration_caps_remove_blockers(void)
 {
     migration_vfio_unblock_postcopy_migration();
+    migration_vfio_unblock_background_snapshot();
 }
 
 bool migrate_cap_set(int cap, bool value, Error **errp)
diff --git a/migration/target.c b/migration/target.c
index 690ecb4dd5..c2be0b39db 100644
--- a/migration/target.c
+++ b/migration/target.c
@@ -37,6 +37,11 @@ void migration_vfio_unblock_postcopy_migration(void)
 {
     vfio_unblock_postcopy_migration();
 }
+
+void migration_vfio_unblock_background_snapshot(void)
+{
+    vfio_unblock_background_snapshot();
+}
 #else
 void migration_populate_vfio_info(MigrationInfo *info)
 {
@@ -54,4 +59,8 @@ bool migration_vfio_mig_active(void)
 void migration_vfio_unblock_postcopy_migration()
 {
 }
+
+void migration_vfio_unblock_background_snapshot(void)
+{
+}
 #endif
-- 
2.26.3



      parent reply	other threads:[~2023-08-28 15:19 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-08-28 15:18 [PATCH 0/6] vfio/migration: Block VFIO migration with postcopy and background snapshot Avihai Horon
2023-08-28 15:18 ` [PATCH 1/6] migration: Add migration prefix to functions in target.c Avihai Horon
2023-08-29 13:23   ` Cédric Le Goater
2023-08-29 14:04   ` Peter Xu
2023-08-29 15:59     ` Avihai Horon
2023-08-28 15:18 ` [PATCH 2/6] vfio/migration: Fail adding device with enable-migration=on and existing blocker Avihai Horon
2023-08-29 13:23   ` Cédric Le Goater
2023-08-28 15:18 ` [PATCH 3/6] vfio/migration: Add vfio_migratable_devices_num() Avihai Horon
2023-08-29 13:24   ` Cédric Le Goater
2023-08-28 15:18 ` [PATCH 4/6] vfio/migration: Change vfio_mig_active() semantics Avihai Horon
2023-08-28 15:18 ` [PATCH 5/6] vfio/migration: Block VFIO migration with postcopy migration Avihai Horon
2023-08-29 13:24   ` Cédric Le Goater
2023-08-29 15:52     ` Avihai Horon
2023-08-29 14:53   ` Peter Xu
2023-08-29 16:20     ` Avihai Horon
2023-08-29 18:27       ` Peter Xu
2023-08-30  7:01         ` Avihai Horon
2023-08-30  8:37           ` Cédric Le Goater
2023-08-30  9:21             ` Avihai Horon
2023-08-30  9:53               ` Cédric Le Goater
2023-08-30 10:12                 ` Avihai Horon
2023-08-30 11:17                   ` Cédric Le Goater
2023-08-30 14:22                     ` Peter Xu
2023-08-30 16:06                       ` Avihai Horon
2023-08-28 15:18 ` Avihai Horon [this message]

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=20230828151842.11303-7-avihaih@nvidia.com \
    --to=avihaih@nvidia.com \
    --cc=alex.williamson@redhat.com \
    --cc=clg@redhat.com \
    --cc=leobras@redhat.com \
    --cc=peterx@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=quintela@redhat.com \
    --cc=yanghliu@redhat.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;
as well as URLs for NNTP newsgroup(s).