Migration pull request

- Li Zhijian's COLO minor fixes
 - Marc-André's virtio-gpu fix
 - Fiona's virtio-net USO fix
 - A couple of migration-test fixes from Thomas
 -----BEGIN PGP SIGNATURE-----
 
 iQJEBAABCAAuFiEEqhtIsKIjJqWkw2TPx5jcdBvsMZ0FAmZObggQHGZhcm9zYXNA
 c3VzZS5kZQAKCRDHmNx0G+wxnWE8D/49RGE+g29qyk9aKx3lU8mSq+ZzmX5GncBt
 5+Mx5qoHDsBCQTE+dQpEVIoeMJ2HIbgbOML4qsnp6Hw/4/TWkfwC/R6+ZmHBevRk
 fVLkVh2JMHVg8Tq+0FO1X1QnMU03uJ7EAuWdDa8HqlJ5dQY/K3gDaku8oQBXk96X
 13pChSbMob76tdb+wiwbdEakabigH7XfrPdI6lzI8MCGTIcPKc/UKTFYuoj/OsNx
 raqy+uBtvKtfHxiaYnIgHIPNAF/1f4tP3iAOcPoZWIMXWxFkE8+ANDJAbWo6xIcL
 DGg/wEzZO/OnXLjOhjvLBUHK/fx4wQ5bsqA09BVxoRyBGblkXr+bcwBLYjgiEqzT
 aniPiAx5W/Db+T7HqZPIWesFYj3cmcwvYUTrx/RPMdC0epG+ZczDMtescHdZbxvt
 Pjs3nFeCLhyYcVhlTI72eXRCxdd/26+r6/OmrBC2+GaZrybM61TvNo+3XvO0Pfhi
 UmwF2EN27XmSMelLvH/MnflUVgBHKDs3CCQzDlxreHq2jMVR0SL7LU5wMJJ58Iok
 M3u74izQM25bwYxiASH+4iRn0puH1mOwgOx28W0uiQfZY/678/lCnwa1Tul15BRE
 fIQZJhyIGzhSpwLqEXmdXdlLQs1isqIgpd/mzKgZ285nLr7kz+4gxCUqiXgVbrl7
 P45Dym1u4g==
 =DDrh
 -----END PGP SIGNATURE-----

Merge tag 'migration-20240522-pull-request' of https://gitlab.com/farosas/qemu into staging

Migration pull request

- Li Zhijian's COLO minor fixes
- Marc-André's virtio-gpu fix
- Fiona's virtio-net USO fix
- A couple of migration-test fixes from Thomas

# -----BEGIN PGP SIGNATURE-----
#
# iQJEBAABCAAuFiEEqhtIsKIjJqWkw2TPx5jcdBvsMZ0FAmZObggQHGZhcm9zYXNA
# c3VzZS5kZQAKCRDHmNx0G+wxnWE8D/49RGE+g29qyk9aKx3lU8mSq+ZzmX5GncBt
# 5+Mx5qoHDsBCQTE+dQpEVIoeMJ2HIbgbOML4qsnp6Hw/4/TWkfwC/R6+ZmHBevRk
# fVLkVh2JMHVg8Tq+0FO1X1QnMU03uJ7EAuWdDa8HqlJ5dQY/K3gDaku8oQBXk96X
# 13pChSbMob76tdb+wiwbdEakabigH7XfrPdI6lzI8MCGTIcPKc/UKTFYuoj/OsNx
# raqy+uBtvKtfHxiaYnIgHIPNAF/1f4tP3iAOcPoZWIMXWxFkE8+ANDJAbWo6xIcL
# DGg/wEzZO/OnXLjOhjvLBUHK/fx4wQ5bsqA09BVxoRyBGblkXr+bcwBLYjgiEqzT
# aniPiAx5W/Db+T7HqZPIWesFYj3cmcwvYUTrx/RPMdC0epG+ZczDMtescHdZbxvt
# Pjs3nFeCLhyYcVhlTI72eXRCxdd/26+r6/OmrBC2+GaZrybM61TvNo+3XvO0Pfhi
# UmwF2EN27XmSMelLvH/MnflUVgBHKDs3CCQzDlxreHq2jMVR0SL7LU5wMJJ58Iok
# M3u74izQM25bwYxiASH+4iRn0puH1mOwgOx28W0uiQfZY/678/lCnwa1Tul15BRE
# fIQZJhyIGzhSpwLqEXmdXdlLQs1isqIgpd/mzKgZ285nLr7kz+4gxCUqiXgVbrl7
# P45Dym1u4g==
# =DDrh
# -----END PGP SIGNATURE-----
# gpg: Signature made Wed 22 May 2024 03:13:28 PM PDT
# gpg:                using RSA key AA1B48B0A22326A5A4C364CFC798DC741BEC319D
# gpg:                issuer "farosas@suse.de"
# gpg: Good signature from "Fabiano Rosas <farosas@suse.de>" [unknown]
# gpg:                 aka "Fabiano Almeida Rosas <fabiano.rosas@suse.com>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: AA1B 48B0 A223 26A5 A4C3  64CF C798 DC74 1BEC 319D

* tag 'migration-20240522-pull-request' of https://gitlab.com/farosas/qemu:
  tests/qtest/migration-test: Fix the check for a successful run of analyze-migration.py
  tests/qtest/migration-test: Run some basic tests on s390x and ppc64 with TCG, too
  hw/core/machine: move compatibility flags for VirtIO-net USO to machine 8.1
  virtio-gpu: fix v2 migration
  migration: fix a typo
  migration: add "exists" info to load-state-field trace
  migration/colo: Tidy up bql_unlock() around bdrv_activate_all()
  migration/colo: make colo_incoming_co() return void
  migration/colo: Minor fix for colo error message

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2024-05-22 15:32:25 -07:00
commit 7e1c004701
10 changed files with 71 additions and 60 deletions

View File

@ -43,6 +43,7 @@ GlobalProperty hw_compat_8_2[] = {
{ "migration", "zero-page-detection", "legacy"}, { "migration", "zero-page-detection", "legacy"},
{ TYPE_VIRTIO_IOMMU_PCI, "granule", "4k" }, { TYPE_VIRTIO_IOMMU_PCI, "granule", "4k" },
{ TYPE_VIRTIO_IOMMU_PCI, "aw-bits", "64" }, { TYPE_VIRTIO_IOMMU_PCI, "aw-bits", "64" },
{ "virtio-gpu-device", "x-scanout-vmstate-version", "1" },
}; };
const size_t hw_compat_8_2_len = G_N_ELEMENTS(hw_compat_8_2); const size_t hw_compat_8_2_len = G_N_ELEMENTS(hw_compat_8_2);
@ -51,15 +52,15 @@ GlobalProperty hw_compat_8_1[] = {
{ "ramfb", "x-migrate", "off" }, { "ramfb", "x-migrate", "off" },
{ "vfio-pci-nohotplug", "x-ramfb-migrate", "off" }, { "vfio-pci-nohotplug", "x-ramfb-migrate", "off" },
{ "igb", "x-pcie-flr-init", "off" }, { "igb", "x-pcie-flr-init", "off" },
{ TYPE_VIRTIO_NET, "host_uso", "off"},
{ TYPE_VIRTIO_NET, "guest_uso4", "off"},
{ TYPE_VIRTIO_NET, "guest_uso6", "off"},
}; };
const size_t hw_compat_8_1_len = G_N_ELEMENTS(hw_compat_8_1); const size_t hw_compat_8_1_len = G_N_ELEMENTS(hw_compat_8_1);
GlobalProperty hw_compat_8_0[] = { GlobalProperty hw_compat_8_0[] = {
{ "migration", "multifd-flush-after-each-section", "on"}, { "migration", "multifd-flush-after-each-section", "on"},
{ TYPE_PCI_DEVICE, "x-pcie-ari-nextfn-1", "on" }, { TYPE_PCI_DEVICE, "x-pcie-ari-nextfn-1", "on" },
{ TYPE_VIRTIO_NET, "host_uso", "off"},
{ TYPE_VIRTIO_NET, "guest_uso4", "off"},
{ TYPE_VIRTIO_NET, "guest_uso6", "off"},
}; };
const size_t hw_compat_8_0_len = G_N_ELEMENTS(hw_compat_8_0); const size_t hw_compat_8_0_len = G_N_ELEMENTS(hw_compat_8_0);

View File

@ -1166,10 +1166,17 @@ static void virtio_gpu_cursor_bh(void *opaque)
virtio_gpu_handle_cursor(&g->parent_obj.parent_obj, g->cursor_vq); virtio_gpu_handle_cursor(&g->parent_obj.parent_obj, g->cursor_vq);
} }
static bool scanout_vmstate_after_v2(void *opaque, int version)
{
struct VirtIOGPUBase *base = container_of(opaque, VirtIOGPUBase, scanout);
struct VirtIOGPU *gpu = container_of(base, VirtIOGPU, parent_obj);
return gpu->scanout_vmstate_version >= 2;
}
static const VMStateDescription vmstate_virtio_gpu_scanout = { static const VMStateDescription vmstate_virtio_gpu_scanout = {
.name = "virtio-gpu-one-scanout", .name = "virtio-gpu-one-scanout",
.version_id = 2, .version_id = 1,
.minimum_version_id = 1,
.fields = (const VMStateField[]) { .fields = (const VMStateField[]) {
VMSTATE_UINT32(resource_id, struct virtio_gpu_scanout), VMSTATE_UINT32(resource_id, struct virtio_gpu_scanout),
VMSTATE_UINT32(width, struct virtio_gpu_scanout), VMSTATE_UINT32(width, struct virtio_gpu_scanout),
@ -1181,12 +1188,18 @@ static const VMStateDescription vmstate_virtio_gpu_scanout = {
VMSTATE_UINT32(cursor.hot_y, struct virtio_gpu_scanout), VMSTATE_UINT32(cursor.hot_y, struct virtio_gpu_scanout),
VMSTATE_UINT32(cursor.pos.x, struct virtio_gpu_scanout), VMSTATE_UINT32(cursor.pos.x, struct virtio_gpu_scanout),
VMSTATE_UINT32(cursor.pos.y, struct virtio_gpu_scanout), VMSTATE_UINT32(cursor.pos.y, struct virtio_gpu_scanout),
VMSTATE_UINT32_V(fb.format, struct virtio_gpu_scanout, 2), VMSTATE_UINT32_TEST(fb.format, struct virtio_gpu_scanout,
VMSTATE_UINT32_V(fb.bytes_pp, struct virtio_gpu_scanout, 2), scanout_vmstate_after_v2),
VMSTATE_UINT32_V(fb.width, struct virtio_gpu_scanout, 2), VMSTATE_UINT32_TEST(fb.bytes_pp, struct virtio_gpu_scanout,
VMSTATE_UINT32_V(fb.height, struct virtio_gpu_scanout, 2), scanout_vmstate_after_v2),
VMSTATE_UINT32_V(fb.stride, struct virtio_gpu_scanout, 2), VMSTATE_UINT32_TEST(fb.width, struct virtio_gpu_scanout,
VMSTATE_UINT32_V(fb.offset, struct virtio_gpu_scanout, 2), scanout_vmstate_after_v2),
VMSTATE_UINT32_TEST(fb.height, struct virtio_gpu_scanout,
scanout_vmstate_after_v2),
VMSTATE_UINT32_TEST(fb.stride, struct virtio_gpu_scanout,
scanout_vmstate_after_v2),
VMSTATE_UINT32_TEST(fb.offset, struct virtio_gpu_scanout,
scanout_vmstate_after_v2),
VMSTATE_END_OF_LIST() VMSTATE_END_OF_LIST()
}, },
}; };
@ -1659,6 +1672,7 @@ static Property virtio_gpu_properties[] = {
DEFINE_PROP_BIT("blob", VirtIOGPU, parent_obj.conf.flags, DEFINE_PROP_BIT("blob", VirtIOGPU, parent_obj.conf.flags,
VIRTIO_GPU_FLAG_BLOB_ENABLED, false), VIRTIO_GPU_FLAG_BLOB_ENABLED, false),
DEFINE_PROP_SIZE("hostmem", VirtIOGPU, parent_obj.conf.hostmem, 0), DEFINE_PROP_SIZE("hostmem", VirtIOGPU, parent_obj.conf.hostmem, 0),
DEFINE_PROP_UINT8("x-scanout-vmstate-version", VirtIOGPU, scanout_vmstate_version, 2),
DEFINE_PROP_END_OF_LIST(), DEFINE_PROP_END_OF_LIST(),
}; };

View File

@ -177,6 +177,7 @@ typedef struct VGPUDMABuf {
struct VirtIOGPU { struct VirtIOGPU {
VirtIOGPUBase parent_obj; VirtIOGPUBase parent_obj;
uint8_t scanout_vmstate_version;
uint64_t conf_max_hostmem; uint64_t conf_max_hostmem;
VirtQueue *ctrl_vq; VirtQueue *ctrl_vq;

View File

@ -49,7 +49,7 @@ void colo_checkpoint_delay_set(void);
* *
* Called with BQL locked, may temporary release BQL. * Called with BQL locked, may temporary release BQL.
*/ */
int coroutine_fn colo_incoming_co(void); void coroutine_fn colo_incoming_co(void);
void colo_shutdown(void); void colo_shutdown(void);
#endif #endif

View File

@ -9,9 +9,8 @@ void colo_shutdown(void)
{ {
} }
int coroutine_fn colo_incoming_co(void) void coroutine_fn colo_incoming_co(void)
{ {
return 0;
} }
void colo_checkpoint_delay_set(void) void colo_checkpoint_delay_set(void)

View File

@ -837,12 +837,11 @@ static void *colo_process_incoming_thread(void *opaque)
/* Make sure all file formats throw away their mutable metadata */ /* Make sure all file formats throw away their mutable metadata */
bql_lock(); bql_lock();
bdrv_activate_all(&local_err); bdrv_activate_all(&local_err);
if (local_err) {
bql_unlock(); bql_unlock();
if (local_err) {
error_report_err(local_err); error_report_err(local_err);
return NULL; return NULL;
} }
bql_unlock();
failover_init_state(); failover_init_state();
@ -928,16 +927,13 @@ out:
return NULL; return NULL;
} }
int coroutine_fn colo_incoming_co(void) void coroutine_fn colo_incoming_co(void)
{ {
MigrationIncomingState *mis = migration_incoming_get_current(); MigrationIncomingState *mis = migration_incoming_get_current();
QemuThread th; QemuThread th;
assert(bql_locked()); assert(bql_locked());
assert(migration_incoming_colo_enabled());
if (!migration_incoming_colo_enabled()) {
return 0;
}
qemu_thread_create(&th, "COLO incoming", colo_process_incoming_thread, qemu_thread_create(&th, "COLO incoming", colo_process_incoming_thread,
mis, QEMU_THREAD_JOINABLE); mis, QEMU_THREAD_JOINABLE);
@ -953,6 +949,4 @@ int coroutine_fn colo_incoming_co(void)
/* We hold the global BQL, so it is safe here */ /* We hold the global BQL, so it is safe here */
colo_release_ram_cache(); colo_release_ram_cache();
return 0;
} }

View File

@ -513,13 +513,13 @@ void migration_incoming_disable_colo(void)
int migration_incoming_enable_colo(void) int migration_incoming_enable_colo(void)
{ {
#ifndef CONFIG_REPLICATION #ifndef CONFIG_REPLICATION
error_report("ENABLE_COLO command come in migration stream, but COLO " error_report("ENABLE_COLO command come in migration stream, but the "
"module is not built in"); "replication module is not built in");
return -ENOTSUP; return -ENOTSUP;
#endif #endif
if (!migrate_colo()) { if (!migrate_colo()) {
error_report("ENABLE_COLO command come in migration stream, but c-colo " error_report("ENABLE_COLO command come in migration stream, but x-colo "
"capability is not set"); "capability is not set");
return -EINVAL; return -EINVAL;
} }
@ -776,9 +776,9 @@ process_incoming_migration_co(void *opaque)
goto fail; goto fail;
} }
if (colo_incoming_co() < 0) { if (migration_incoming_colo_enabled()) {
error_setg(&local_err, "colo incoming failed"); /* yield until COLO exit */
goto fail; colo_incoming_co();
} }
migration_bh_schedule(process_incoming_migration_bh, mis); migration_bh_schedule(process_incoming_migration_bh, mis);

View File

@ -58,7 +58,7 @@ postcopy_page_req_sync(void *host_addr) "sync page req %p"
vmstate_load_field_error(const char *field, int ret) "field \"%s\" load failed, ret = %d" vmstate_load_field_error(const char *field, int ret) "field \"%s\" load failed, ret = %d"
vmstate_load_state(const char *name, int version_id) "%s v%d" vmstate_load_state(const char *name, int version_id) "%s v%d"
vmstate_load_state_end(const char *name, const char *reason, int val) "%s %s/%d" vmstate_load_state_end(const char *name, const char *reason, int val) "%s %s/%d"
vmstate_load_state_field(const char *name, const char *field) "%s:%s" vmstate_load_state_field(const char *name, const char *field, bool exists) "%s:%s exists=%d"
vmstate_n_elems(const char *name, int n_elems) "%s: %d" vmstate_n_elems(const char *name, int n_elems) "%s: %d"
vmstate_subsection_load(const char *parent) "%s" vmstate_subsection_load(const char *parent) "%s"
vmstate_subsection_load_bad(const char *parent, const char *sub, const char *sub2) "%s: %s/%s" vmstate_subsection_load_bad(const char *parent, const char *sub, const char *sub2) "%s: %s/%s"

View File

@ -128,8 +128,9 @@ int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
} }
} }
while (field->name) { while (field->name) {
trace_vmstate_load_state_field(vmsd->name, field->name); bool exists = vmstate_field_exists(vmsd, field, opaque, version_id);
if (vmstate_field_exists(vmsd, field, opaque, version_id)) { trace_vmstate_load_state_field(vmsd->name, field->name, exists);
if (exists) {
void *first_elem = opaque + field->offset; void *first_elem = opaque + field->offset;
int i, n_elems = vmstate_n_elems(opaque, field); int i, n_elems = vmstate_n_elems(opaque, field);
int size = vmstate_size(opaque, field); int size = vmstate_size(opaque, field);
@ -478,7 +479,7 @@ static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd,
len = qemu_peek_byte(f, 1); len = qemu_peek_byte(f, 1);
if (len < strlen(vmsd->name) + 1) { if (len < strlen(vmsd->name) + 1) {
/* subsection name has be be "section_name/a" */ /* subsection name has to be "section_name/a" */
trace_vmstate_subsection_load_bad(vmsd->name, "(short)", ""); trace_vmstate_subsection_load_bad(vmsd->name, "(short)", "");
return 0; return 0;
} }

View File

@ -1604,7 +1604,7 @@ static void test_analyze_script(void)
} }
g_assert(waitpid(pid, &wstatus, 0) == pid); g_assert(waitpid(pid, &wstatus, 0) == pid);
if (WIFEXITED(wstatus) && WEXITSTATUS(wstatus) != 0) { if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus) != 0) {
g_test_message("Failed to analyze the migration stream"); g_test_message("Failed to analyze the migration stream");
g_test_fail(); g_test_fail();
} }
@ -3437,26 +3437,6 @@ int main(int argc, char **argv)
arch = qtest_get_arch(); arch = qtest_get_arch();
is_x86 = !strcmp(arch, "i386") || !strcmp(arch, "x86_64"); is_x86 = !strcmp(arch, "i386") || !strcmp(arch, "x86_64");
/*
* On ppc64, the test only works with kvm-hv, but not with kvm-pr and TCG
* is touchy due to race conditions on dirty bits (especially on PPC for
* some reason)
*/
if (g_str_equal(arch, "ppc64") &&
(!has_kvm || access("/sys/module/kvm_hv", F_OK))) {
g_test_message("Skipping test: kvm_hv not available");
return g_test_run();
}
/*
* Similar to ppc64, s390x seems to be touchy with TCG, so disable it
* there until the problems are resolved
*/
if (g_str_equal(arch, "s390x") && !has_kvm) {
g_test_message("Skipping test: s390x host with KVM is required");
return g_test_run();
}
tmpfs = g_dir_make_tmp("migration-test-XXXXXX", &err); tmpfs = g_dir_make_tmp("migration-test-XXXXXX", &err);
if (!tmpfs) { if (!tmpfs) {
g_test_message("Can't create temporary directory in %s: %s", g_test_message("Can't create temporary directory in %s: %s",
@ -3466,6 +3446,31 @@ int main(int argc, char **argv)
module_call_init(MODULE_INIT_QOM); module_call_init(MODULE_INIT_QOM);
migration_test_add("/migration/bad_dest", test_baddest);
#ifndef _WIN32
migration_test_add("/migration/analyze-script", test_analyze_script);
#endif
/*
* On ppc64, the test only works with kvm-hv, but not with kvm-pr and TCG
* is touchy due to race conditions on dirty bits (especially on PPC for
* some reason)
*/
if (g_str_equal(arch, "ppc64") &&
(!has_kvm || access("/sys/module/kvm_hv", F_OK))) {
g_test_message("Skipping tests: kvm_hv not available");
goto test_add_done;
}
/*
* Similar to ppc64, s390x seems to be touchy with TCG, so disable it
* there until the problems are resolved
*/
if (g_str_equal(arch, "s390x") && !has_kvm) {
g_test_message("Skipping tests: s390x host with KVM is required");
goto test_add_done;
}
if (is_x86) { if (is_x86) {
migration_test_add("/migration/precopy/unix/suspend/live", migration_test_add("/migration/precopy/unix/suspend/live",
test_precopy_unix_suspend_live); test_precopy_unix_suspend_live);
@ -3491,12 +3496,6 @@ int main(int argc, char **argv)
} }
} }
migration_test_add("/migration/bad_dest", test_baddest);
#ifndef _WIN32
if (!g_str_equal(arch, "s390x")) {
migration_test_add("/migration/analyze-script", test_analyze_script);
}
#endif
migration_test_add("/migration/precopy/unix/plain", migration_test_add("/migration/precopy/unix/plain",
test_precopy_unix_plain); test_precopy_unix_plain);
migration_test_add("/migration/precopy/unix/xbzrle", migration_test_add("/migration/precopy/unix/xbzrle",
@ -3653,6 +3652,8 @@ int main(int argc, char **argv)
test_vcpu_dirty_limit); test_vcpu_dirty_limit);
} }
test_add_done:
ret = g_test_run(); ret = g_test_run();
g_assert_cmpint(ret, ==, 0); g_assert_cmpint(ret, ==, 0);