[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v5 11/14] vfio/migration: Optimize vfio_save_pending()
From: |
Avihai Horon |
Subject: |
[PATCH v5 11/14] vfio/migration: Optimize vfio_save_pending() |
Date: |
Thu, 29 Dec 2022 13:03:42 +0200 |
During pre-copy phase of migration vfio_save_pending() is called
repeatedly and queries the VFIO device for its pending data size.
As long as pending RAM size is over the threshold, migration can't
converge and be completed. Therefore, during this time there is no
point in querying the VFIO device pending data size.
Avoid these unnecessary queries by issuing them in a RAM pre-copy
notifier instead of vfio_save_pending().
This way the VFIO device is queried only when RAM pending data is
below the threshold, when there is an actual chance for migration to
converge.
Signed-off-by: Avihai Horon <avihaih@nvidia.com>
---
include/hw/vfio/vfio-common.h | 2 ++
hw/vfio/migration.c | 59 +++++++++++++++++++++++++----------
hw/vfio/trace-events | 1 +
3 files changed, 46 insertions(+), 16 deletions(-)
diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index 2ec3346fea..113f8d9208 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -65,11 +65,13 @@ typedef struct VFIOMigration {
uint32_t device_state_v1;
int vm_running;
Notifier migration_state;
+ NotifierWithReturn migration_data;
uint64_t pending_bytes;
enum vfio_device_mig_state device_state;
int data_fd;
void *data_buffer;
size_t data_buffer_size;
+ uint64_t stop_copy_size;
bool v2;
} VFIOMigration;
diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
index 645fa33a46..242ea211f5 100644
--- a/hw/vfio/migration.c
+++ b/hw/vfio/migration.c
@@ -657,32 +657,19 @@ static void vfio_v1_save_cleanup(void *opaque)
trace_vfio_save_cleanup(vbasedev->name);
}
-/*
- * Migration size of VFIO devices can be as little as a few KBs or as big as
- * many GBs. This value should be big enough to cover the worst case.
- */
-#define VFIO_MIG_STOP_COPY_SIZE (100 * GiB)
static void vfio_save_pending(void *opaque, uint64_t threshold_size,
uint64_t *res_precopy_only,
uint64_t *res_compatible,
uint64_t *res_postcopy_only)
{
VFIODevice *vbasedev = opaque;
- uint64_t stop_copy_size;
-
- if (vfio_query_stop_copy_size(vbasedev, &stop_copy_size)) {
- /*
- * Failed to get pending migration size. Report big pending size so
- * downtime limit won't be violated.
- */
- stop_copy_size = VFIO_MIG_STOP_COPY_SIZE;
- }
+ VFIOMigration *migration = vbasedev->migration;
- *res_precopy_only += stop_copy_size;
+ *res_precopy_only += migration->stop_copy_size;
trace_vfio_save_pending(vbasedev->name, *res_precopy_only,
*res_postcopy_only, *res_compatible,
- stop_copy_size);
+ migration->stop_copy_size);
}
static void vfio_v1_save_pending(void *opaque, uint64_t threshold_size,
@@ -1109,6 +1096,40 @@ static void vfio_migration_state_notifier(Notifier
*notifier, void *data)
}
}
+/*
+ * Migration size of VFIO devices can be as little as a few KBs or as big as
+ * many GBs. This value should be big enough to cover the worst case.
+ */
+#define VFIO_MIG_STOP_COPY_SIZE (100 * GiB)
+static int vfio_migration_data_notifier(NotifierWithReturn *n, void *data)
+{
+ VFIOMigration *migration = container_of(n, VFIOMigration, migration_data);
+ VFIODevice *vbasedev = migration->vbasedev;
+ PrecopyNotifyData *pnd = data;
+
+ if (pnd->reason != PRECOPY_NOTIFY_AFTER_BITMAP_SYNC) {
+ return 0;
+ }
+
+ /* No need to get pending size when finishing migration */
+ if (runstate_check(RUN_STATE_FINISH_MIGRATE)) {
+ return 0;
+ }
+
+ if (vfio_query_stop_copy_size(vbasedev, &migration->stop_copy_size)) {
+ /*
+ * Failed to get pending migration size. Report big pending size so
+ * downtime limit won't be violated.
+ */
+ migration->stop_copy_size = VFIO_MIG_STOP_COPY_SIZE;
+ }
+
+ trace_vfio_migration_data_notifier(vbasedev->name,
+ migration->stop_copy_size);
+
+ return 0;
+}
+
static void vfio_migration_exit(VFIODevice *vbasedev)
{
VFIOMigration *migration = vbasedev->migration;
@@ -1220,6 +1241,9 @@ static int vfio_migration_init(VFIODevice *vbasedev)
migration->vm_state = qdev_add_vm_change_state_handler(
vbasedev->dev, vfio_vmstate_change, vbasedev);
+
+ migration->migration_data.notify = vfio_migration_data_notifier;
+ precopy_add_notifier(&migration->migration_data);
} else {
register_savevm_live(id, VMSTATE_INSTANCE_ID_ANY, 1,
&savevm_vfio_v1_handlers, vbasedev);
@@ -1278,6 +1302,9 @@ void vfio_migration_finalize(VFIODevice *vbasedev)
if (vbasedev->migration) {
VFIOMigration *migration = vbasedev->migration;
+ if (migration->v2) {
+ precopy_remove_notifier(&migration->migration_data);
+ }
remove_migration_state_change_notifier(&migration->migration_state);
qemu_del_vm_change_state_handler(migration->vm_state);
unregister_savevm(VMSTATE_IF(vbasedev->dev), "vfio", vbasedev);
diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events
index e7b3b4658c..a8a64f0627 100644
--- a/hw/vfio/trace-events
+++ b/hw/vfio/trace-events
@@ -173,3 +173,4 @@ vfio_load_cleanup(const char *name) " (%s)"
vfio_get_dirty_bitmap(int fd, uint64_t iova, uint64_t size, uint64_t
bitmap_size, uint64_t start) "container fd=%d, iova=0x%"PRIx64" size=
0x%"PRIx64" bitmap_size=0x%"PRIx64" start=0x%"PRIx64
vfio_iommu_map_dirty_notify(uint64_t iova_start, uint64_t iova_end) "iommu
dirty @ 0x%"PRIx64" - 0x%"PRIx64
vfio_save_block(const char *name, int data_size) " (%s) data_size %d"
+vfio_migration_data_notifier(const char *name, uint64_t stopcopy_size) " (%s)
stopcopy size 0x%"PRIx64
--
2.26.3
- [PATCH v5 04/14] vfio/migration: Fix NULL pointer dereference bug, (continued)
- [PATCH v5 04/14] vfio/migration: Fix NULL pointer dereference bug, Avihai Horon, 2022/12/29
- [PATCH v5 05/14] vfio/migration: Allow migration without VFIO IOMMU dirty tracking support, Avihai Horon, 2022/12/29
- [PATCH v5 07/14] vfio/common: Change vfio_devices_all_running_and_saving() logic to equivalent one, Avihai Horon, 2022/12/29
- [PATCH v5 06/14] migration/qemu-file: Add qemu_file_get_to_fd(), Avihai Horon, 2022/12/29
- [PATCH v5 08/14] vfio/migration: Move migration v1 logic to vfio_migration_init(), Avihai Horon, 2022/12/29
- [PATCH v5 09/14] vfio/migration: Rename functions/structs related to v1 protocol, Avihai Horon, 2022/12/29
- [PATCH v5 10/14] vfio/migration: Implement VFIO migration protocol v2, Avihai Horon, 2022/12/29
- [PATCH v5 13/14] vfio: Alphabetize migration section of VFIO trace-events file, Avihai Horon, 2022/12/29
- [PATCH v5 12/14] vfio/migration: Remove VFIO migration protocol v1, Avihai Horon, 2022/12/29
- [PATCH v5 14/14] docs/devel: Align VFIO migration docs to v2 protocol, Avihai Horon, 2022/12/29
- [PATCH v5 11/14] vfio/migration: Optimize vfio_save_pending(),
Avihai Horon <=