vfio/migration: Add x-migration-multifd-transfer VFIO property

This property allows configuring whether to transfer the particular device
state via multifd channels when live migrating that device.

It defaults to AUTO, which means that VFIO device state transfer via
multifd channels is attempted in configurations that otherwise support it.

Signed-off-by: Maciej S. Szmigiero <maciej.szmigiero@oracle.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Link: https://lore.kernel.org/qemu-devel/d6dbb326e3d53c7104d62c96c9e3dd64e1c7b940.1741124640.git.maciej.szmigiero@oracle.com
[ clg: Added documentation ]
Signed-off-by: Cédric Le Goater <clg@redhat.com>
This commit is contained in:
Maciej S. Szmigiero 2025-03-04 23:03:58 +01:00 committed by Cédric Le Goater
parent 6d644baef2
commit 623af41dd3
4 changed files with 41 additions and 1 deletions

View file

@ -232,3 +232,18 @@ Postcopy
======== ========
Postcopy migration is currently not supported for VFIO devices. Postcopy migration is currently not supported for VFIO devices.
Multifd
=======
Starting from QEMU version 10.0 there's a possibility to transfer VFIO device
_STOP_COPY state via multifd channels. This helps reduce downtime - especially
with multiple VFIO devices or with devices having a large migration state.
As an additional benefit, setting the VFIO device to _STOP_COPY state and
saving its config space is also parallelized (run in a separate thread) in
such migration mode.
The multifd VFIO device state transfer is controlled by
"x-migration-multifd-transfer" VFIO device property. This property defaults to
AUTO, which means that VFIO device state transfer via multifd channels is
attempted in configurations that otherwise support it.

View file

@ -476,18 +476,34 @@ bool vfio_multifd_transfer_supported(void)
bool vfio_multifd_transfer_enabled(VFIODevice *vbasedev) bool vfio_multifd_transfer_enabled(VFIODevice *vbasedev)
{ {
return false; VFIOMigration *migration = vbasedev->migration;
return migration->multifd_transfer;
} }
bool vfio_multifd_setup(VFIODevice *vbasedev, bool alloc_multifd, Error **errp) bool vfio_multifd_setup(VFIODevice *vbasedev, bool alloc_multifd, Error **errp)
{ {
VFIOMigration *migration = vbasedev->migration; VFIOMigration *migration = vbasedev->migration;
if (vbasedev->migration_multifd_transfer == ON_OFF_AUTO_AUTO) {
migration->multifd_transfer = vfio_multifd_transfer_supported();
} else {
migration->multifd_transfer =
vbasedev->migration_multifd_transfer == ON_OFF_AUTO_ON;
}
if (!vfio_multifd_transfer_enabled(vbasedev)) { if (!vfio_multifd_transfer_enabled(vbasedev)) {
/* Nothing further to check or do */ /* Nothing further to check or do */
return true; return true;
} }
if (!vfio_multifd_transfer_supported()) {
error_setg(errp,
"%s: Multifd device transfer requested but unsupported in the current config",
vbasedev->name);
return false;
}
if (alloc_multifd) { if (alloc_multifd) {
assert(!migration->multifd); assert(!migration->multifd);
migration->multifd = vfio_multifd_new(); migration->multifd = vfio_multifd_new();

View file

@ -3381,6 +3381,9 @@ static const Property vfio_pci_dev_properties[] = {
VFIO_FEATURE_ENABLE_IGD_OPREGION_BIT, false), VFIO_FEATURE_ENABLE_IGD_OPREGION_BIT, false),
DEFINE_PROP_ON_OFF_AUTO("enable-migration", VFIOPCIDevice, DEFINE_PROP_ON_OFF_AUTO("enable-migration", VFIOPCIDevice,
vbasedev.enable_migration, ON_OFF_AUTO_AUTO), vbasedev.enable_migration, ON_OFF_AUTO_AUTO),
DEFINE_PROP_ON_OFF_AUTO("x-migration-multifd-transfer", VFIOPCIDevice,
vbasedev.migration_multifd_transfer,
ON_OFF_AUTO_AUTO),
DEFINE_PROP_BOOL("migration-events", VFIOPCIDevice, DEFINE_PROP_BOOL("migration-events", VFIOPCIDevice,
vbasedev.migration_events, false), vbasedev.migration_events, false),
DEFINE_PROP_BOOL("x-no-mmap", VFIOPCIDevice, vbasedev.no_mmap, false), DEFINE_PROP_BOOL("x-no-mmap", VFIOPCIDevice, vbasedev.no_mmap, false),
@ -3553,6 +3556,10 @@ static void vfio_pci_dev_class_init(ObjectClass *klass, void *data)
"Skip config space check for Vendor Specific Capability. " "Skip config space check for Vendor Specific Capability. "
"Setting to false will enforce strict checking of VSC content " "Setting to false will enforce strict checking of VSC content "
"(DEBUG)"); "(DEBUG)");
object_class_property_set_description(klass, /* 10.0 */
"x-migration-multifd-transfer",
"Transfer this device state via "
"multifd channels when live migrating it");
} }
static const TypeInfo vfio_pci_dev_info = { static const TypeInfo vfio_pci_dev_info = {

View file

@ -91,6 +91,7 @@ typedef struct VFIOMigration {
uint64_t mig_flags; uint64_t mig_flags;
uint64_t precopy_init_size; uint64_t precopy_init_size;
uint64_t precopy_dirty_size; uint64_t precopy_dirty_size;
bool multifd_transfer;
VFIOMultifd *multifd; VFIOMultifd *multifd;
bool initial_data_sent; bool initial_data_sent;
@ -153,6 +154,7 @@ typedef struct VFIODevice {
bool no_mmap; bool no_mmap;
bool ram_block_discard_allowed; bool ram_block_discard_allowed;
OnOffAuto enable_migration; OnOffAuto enable_migration;
OnOffAuto migration_multifd_transfer;
bool migration_events; bool migration_events;
VFIODeviceOps *ops; VFIODeviceOps *ops;
unsigned int num_irqs; unsigned int num_irqs;