mirror of
https://github.com/qemu/qemu.git
synced 2025-08-15 05:06:56 +00:00
migration: check RDMA and capabilities are compatible on both sides
Depending on the order of starting RDMA and setting capability, they can be categorized into the following scenarios: Source: S1: [set capabilities] -> [Start RDMA outgoing] Destination: D1: [set capabilities] -> [Start RDMA incoming] D2: [Start RDMA incoming] -> [set capabilities] Previously, compatibility between RDMA and capabilities was verified only in scenario D1, potentially causing migration failures in other situations. For scenarios S1 and D1, we can seamlessly incorporate migration_transport_compatible() to address compatibility between channels and capabilities vs transport. For scenario D2, ensure compatibility within migrate_caps_check(). Reviewed-by: Peter Xu <peterx@redhat.com> Signed-off-by: Li Zhijian <lizhijian@fujitsu.com> Message-ID: <20250305062825.772629-3-lizhijian@fujitsu.com> Signed-off-by: Fabiano Rosas <farosas@suse.de>
This commit is contained in:
parent
5134cf9b5d
commit
57be554c29
@ -259,6 +259,24 @@ migration_channels_and_transport_compatible(MigrationAddress *addr,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
migration_capabilities_and_transport_compatible(MigrationAddress *addr,
|
||||||
|
Error **errp)
|
||||||
|
{
|
||||||
|
if (addr->transport == MIGRATION_ADDRESS_TYPE_RDMA) {
|
||||||
|
return migrate_rdma_caps_check(migrate_get_current()->capabilities,
|
||||||
|
errp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool migration_transport_compatible(MigrationAddress *addr, Error **errp)
|
||||||
|
{
|
||||||
|
return migration_channels_and_transport_compatible(addr, errp) &&
|
||||||
|
migration_capabilities_and_transport_compatible(addr, errp);
|
||||||
|
}
|
||||||
|
|
||||||
static gint page_request_addr_cmp(gconstpointer ap, gconstpointer bp)
|
static gint page_request_addr_cmp(gconstpointer ap, gconstpointer bp)
|
||||||
{
|
{
|
||||||
uintptr_t a = (uintptr_t) ap, b = (uintptr_t) bp;
|
uintptr_t a = (uintptr_t) ap, b = (uintptr_t) bp;
|
||||||
@ -750,7 +768,7 @@ static void qemu_start_incoming_migration(const char *uri, bool has_channels,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* transport mechanism not suitable for migration? */
|
/* transport mechanism not suitable for migration? */
|
||||||
if (!migration_channels_and_transport_compatible(addr, errp)) {
|
if (!migration_transport_compatible(addr, errp)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -769,14 +787,6 @@ static void qemu_start_incoming_migration(const char *uri, bool has_channels,
|
|||||||
}
|
}
|
||||||
#ifdef CONFIG_RDMA
|
#ifdef CONFIG_RDMA
|
||||||
} else if (addr->transport == MIGRATION_ADDRESS_TYPE_RDMA) {
|
} else if (addr->transport == MIGRATION_ADDRESS_TYPE_RDMA) {
|
||||||
if (migrate_xbzrle()) {
|
|
||||||
error_setg(errp, "RDMA and XBZRLE can't be used together");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (migrate_multifd()) {
|
|
||||||
error_setg(errp, "RDMA and multifd can't be used together");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
rdma_start_incoming_migration(&addr->u.rdma, errp);
|
rdma_start_incoming_migration(&addr->u.rdma, errp);
|
||||||
#endif
|
#endif
|
||||||
} else if (addr->transport == MIGRATION_ADDRESS_TYPE_EXEC) {
|
} else if (addr->transport == MIGRATION_ADDRESS_TYPE_EXEC) {
|
||||||
@ -2208,7 +2218,7 @@ void qmp_migrate(const char *uri, bool has_channels,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* transport mechanism not suitable for migration? */
|
/* transport mechanism not suitable for migration? */
|
||||||
if (!migration_channels_and_transport_compatible(addr, errp)) {
|
if (!migration_transport_compatible(addr, errp)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -448,6 +448,20 @@ static bool migrate_incoming_started(void)
|
|||||||
return !!migration_incoming_get_current()->transport_data;
|
return !!migration_incoming_get_current()->transport_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool migrate_rdma_caps_check(bool *caps, Error **errp)
|
||||||
|
{
|
||||||
|
if (caps[MIGRATION_CAPABILITY_XBZRLE]) {
|
||||||
|
error_setg(errp, "RDMA and XBZRLE can't be used together");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (caps[MIGRATION_CAPABILITY_MULTIFD]) {
|
||||||
|
error_setg(errp, "RDMA and multifd can't be used together");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @migration_caps_check - check capability compatibility
|
* @migration_caps_check - check capability compatibility
|
||||||
*
|
*
|
||||||
@ -611,6 +625,13 @@ bool migrate_caps_check(bool *old_caps, bool *new_caps, Error **errp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* On destination side, check the cases that capability is being set
|
||||||
|
* after incoming thread has started.
|
||||||
|
*/
|
||||||
|
if (migrate_rdma() && !migrate_rdma_caps_check(new_caps, errp)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,6 +57,7 @@ bool migrate_tls(void);
|
|||||||
|
|
||||||
/* capabilities helpers */
|
/* capabilities helpers */
|
||||||
|
|
||||||
|
bool migrate_rdma_caps_check(bool *caps, Error **errp);
|
||||||
bool migrate_caps_check(bool *old_caps, bool *new_caps, Error **errp);
|
bool migrate_caps_check(bool *old_caps, bool *new_caps, Error **errp);
|
||||||
|
|
||||||
/* parameters */
|
/* parameters */
|
||||||
|
Loading…
Reference in New Issue
Block a user