vfio/migration: Emit VFIO migration QAPI event
Emit VFIO migration QAPI event when a VFIO device changes its migration state. This can be used by management applications to get updates on the current state of the VFIO device for their own purposes. A new per VFIO device capability, "migration-events", is added so events can be enabled only for the required devices. It is disabled by default. Signed-off-by: Avihai Horon <avihaih@nvidia.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Signed-off-by: Cédric Le Goater <clg@redhat.com>
This commit is contained in:
parent
a0359b56ec
commit
5e1f8905ca
@ -24,6 +24,7 @@
|
|||||||
#include "migration/register.h"
|
#include "migration/register.h"
|
||||||
#include "migration/blocker.h"
|
#include "migration/blocker.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
|
#include "qapi/qapi-events-vfio.h"
|
||||||
#include "exec/ramlist.h"
|
#include "exec/ramlist.h"
|
||||||
#include "exec/ram_addr.h"
|
#include "exec/ram_addr.h"
|
||||||
#include "pci.h"
|
#include "pci.h"
|
||||||
@ -80,6 +81,58 @@ static const char *mig_state_to_str(enum vfio_device_mig_state state)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VfioMigrationState
|
||||||
|
mig_state_to_qapi_state(enum vfio_device_mig_state state)
|
||||||
|
{
|
||||||
|
switch (state) {
|
||||||
|
case VFIO_DEVICE_STATE_STOP:
|
||||||
|
return QAPI_VFIO_MIGRATION_STATE_STOP;
|
||||||
|
case VFIO_DEVICE_STATE_RUNNING:
|
||||||
|
return QAPI_VFIO_MIGRATION_STATE_RUNNING;
|
||||||
|
case VFIO_DEVICE_STATE_STOP_COPY:
|
||||||
|
return QAPI_VFIO_MIGRATION_STATE_STOP_COPY;
|
||||||
|
case VFIO_DEVICE_STATE_RESUMING:
|
||||||
|
return QAPI_VFIO_MIGRATION_STATE_RESUMING;
|
||||||
|
case VFIO_DEVICE_STATE_RUNNING_P2P:
|
||||||
|
return QAPI_VFIO_MIGRATION_STATE_RUNNING_P2P;
|
||||||
|
case VFIO_DEVICE_STATE_PRE_COPY:
|
||||||
|
return QAPI_VFIO_MIGRATION_STATE_PRE_COPY;
|
||||||
|
case VFIO_DEVICE_STATE_PRE_COPY_P2P:
|
||||||
|
return QAPI_VFIO_MIGRATION_STATE_PRE_COPY_P2P;
|
||||||
|
default:
|
||||||
|
g_assert_not_reached();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vfio_migration_send_event(VFIODevice *vbasedev)
|
||||||
|
{
|
||||||
|
VFIOMigration *migration = vbasedev->migration;
|
||||||
|
DeviceState *dev = vbasedev->dev;
|
||||||
|
g_autofree char *qom_path = NULL;
|
||||||
|
Object *obj;
|
||||||
|
|
||||||
|
if (!vbasedev->migration_events) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_assert(vbasedev->ops->vfio_get_object);
|
||||||
|
obj = vbasedev->ops->vfio_get_object(vbasedev);
|
||||||
|
g_assert(obj);
|
||||||
|
qom_path = object_get_canonical_path(obj);
|
||||||
|
|
||||||
|
qapi_event_send_vfio_migration(
|
||||||
|
dev->id, qom_path, mig_state_to_qapi_state(migration->device_state));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vfio_migration_set_device_state(VFIODevice *vbasedev,
|
||||||
|
enum vfio_device_mig_state state)
|
||||||
|
{
|
||||||
|
VFIOMigration *migration = vbasedev->migration;
|
||||||
|
|
||||||
|
migration->device_state = state;
|
||||||
|
vfio_migration_send_event(vbasedev);
|
||||||
|
}
|
||||||
|
|
||||||
static int vfio_migration_set_state(VFIODevice *vbasedev,
|
static int vfio_migration_set_state(VFIODevice *vbasedev,
|
||||||
enum vfio_device_mig_state new_state,
|
enum vfio_device_mig_state new_state,
|
||||||
enum vfio_device_mig_state recover_state,
|
enum vfio_device_mig_state recover_state,
|
||||||
@ -131,12 +184,12 @@ static int vfio_migration_set_state(VFIODevice *vbasedev,
|
|||||||
goto reset_device;
|
goto reset_device;
|
||||||
}
|
}
|
||||||
|
|
||||||
migration->device_state = recover_state;
|
vfio_migration_set_device_state(vbasedev, recover_state);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
migration->device_state = new_state;
|
vfio_migration_set_device_state(vbasedev, new_state);
|
||||||
if (mig_state->data_fd != -1) {
|
if (mig_state->data_fd != -1) {
|
||||||
if (migration->data_fd != -1) {
|
if (migration->data_fd != -1) {
|
||||||
/*
|
/*
|
||||||
@ -162,7 +215,7 @@ reset_device:
|
|||||||
strerror(errno));
|
strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
migration->device_state = VFIO_DEVICE_STATE_RUNNING;
|
vfio_migration_set_device_state(vbasedev, VFIO_DEVICE_STATE_RUNNING);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -3388,6 +3388,8 @@ static 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_BOOL("migration-events", VFIOPCIDevice,
|
||||||
|
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),
|
||||||
DEFINE_PROP_BOOL("x-balloon-allowed", VFIOPCIDevice,
|
DEFINE_PROP_BOOL("x-balloon-allowed", VFIOPCIDevice,
|
||||||
vbasedev.ram_block_discard_allowed, false),
|
vbasedev.ram_block_discard_allowed, false),
|
||||||
|
@ -115,6 +115,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;
|
||||||
|
bool migration_events;
|
||||||
VFIODeviceOps *ops;
|
VFIODeviceOps *ops;
|
||||||
unsigned int num_irqs;
|
unsigned int num_irqs;
|
||||||
unsigned int num_regions;
|
unsigned int num_regions;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user