diff --git a/migration/migration.c b/migration/migration.c index 3dea06d577..ae2be31557 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -378,6 +378,11 @@ void migration_incoming_state_destroy(void) struct MigrationIncomingState *mis = migration_incoming_get_current(); multifd_recv_cleanup(); + /* + * RAM state cleanup needs to happen after multifd cleanup, because + * multifd threads can use some of its states (receivedmap). + */ + qemu_loadvm_state_cleanup(); if (mis->to_src_file) { /* Tell source that we are done */ diff --git a/migration/multifd-qatzip.c b/migration/multifd-qatzip.c index 3c787ed879..7b68397625 100644 --- a/migration/multifd-qatzip.c +++ b/migration/multifd-qatzip.c @@ -160,7 +160,8 @@ static void qatzip_send_cleanup(MultiFDSendParams *p, Error **errp) */ static int qatzip_send_prepare(MultiFDSendParams *p, Error **errp) { - MultiFDPages_t *pages = p->pages; + uint32_t page_size = multifd_ram_page_size(); + MultiFDPages_t *pages = &p->data->u.ram; QatzipData *q = p->compress_data; int ret; unsigned int in_len, out_len; @@ -179,12 +180,12 @@ static int qatzip_send_prepare(MultiFDSendParams *p, Error **errp) * implementation. */ for (int i = 0; i < pages->normal_num; i++) { - memcpy(q->in_buf + (i * p->page_size), + memcpy(q->in_buf + (i * page_size), pages->block->host + pages->offset[i], - p->page_size); + page_size); } - in_len = pages->normal_num * p->page_size; + in_len = pages->normal_num * page_size; if (in_len > q->in_len) { error_setg(errp, "multifd %u: unexpectedly large input", p->id); return -1; @@ -197,7 +198,7 @@ static int qatzip_send_prepare(MultiFDSendParams *p, Error **errp) p->id, ret); return -1; } - if (in_len != pages->normal_num * p->page_size) { + if (in_len != pages->normal_num * page_size) { error_setg(errp, "multifd %u: QATzip failed to compress all input", p->id); return -1; @@ -329,7 +330,8 @@ static int qatzip_recv(MultiFDRecvParams *p, Error **errp) int ret; unsigned int in_len, out_len; uint32_t in_size = p->next_packet_size; - uint32_t expected_size = p->normal_num * p->page_size; + uint32_t page_size = multifd_ram_page_size(); + uint32_t expected_size = p->normal_num * page_size; uint32_t flags = p->flags & MULTIFD_FLAG_COMPRESSION_MASK; if (in_size > q->in_len) { @@ -370,9 +372,7 @@ static int qatzip_recv(MultiFDRecvParams *p, Error **errp) /* Copy each page to its appropriate location. */ for (int i = 0; i < p->normal_num; i++) { - memcpy(p->host + p->normal[i], - q->out_buf + p->page_size * i, - p->page_size); + memcpy(p->host + p->normal[i], q->out_buf + page_size * i, page_size); } return 0; } diff --git a/migration/multifd-zstd.c b/migration/multifd-zstd.c index 53da33e048..abed140855 100644 --- a/migration/multifd-zstd.c +++ b/migration/multifd-zstd.c @@ -123,9 +123,9 @@ static int multifd_zstd_send_prepare(MultiFDSendParams *p, Error **errp) */ do { ret = ZSTD_compressStream2(z->zcs, &z->out, &z->in, flush); - } while (ret > 0 && (z->in.size - z->in.pos > 0) - && (z->out.size - z->out.pos > 0)); - if (ret > 0 && (z->in.size - z->in.pos > 0)) { + } while (ret > 0 && (z->in.size > z->in.pos) + && (z->out.size > z->out.pos)); + if (ret > 0 && (z->in.size > z->in.pos)) { error_setg(errp, "multifd %u: compressStream buffer too small", p->id); return -1; @@ -243,7 +243,7 @@ static int multifd_zstd_recv(MultiFDRecvParams *p, Error **errp) */ do { ret = ZSTD_decompressStream(z->zds, &z->out, &z->in); - } while (ret > 0 && (z->in.size - z->in.pos > 0) + } while (ret > 0 && (z->in.size > z->in.pos) && (z->out.pos < page_size)); if (ret > 0 && (z->out.pos < page_size)) { error_setg(errp, "multifd %u: decompressStream buffer too small", diff --git a/migration/savevm.c b/migration/savevm.c index d500eae979..7e1e27182a 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -2732,13 +2732,11 @@ static int qemu_loadvm_state_header(QEMUFile *f) if (migrate_get_current()->send_configuration) { if (qemu_get_byte(f) != QEMU_VM_CONFIGURATION) { error_report("Configuration section missing"); - qemu_loadvm_state_cleanup(); return -EINVAL; } ret = vmstate_load_state(f, &vmstate_configuration, &savevm_state, 0); if (ret) { - qemu_loadvm_state_cleanup(); return ret; } } @@ -2981,7 +2979,10 @@ int qemu_loadvm_state(QEMUFile *f) trace_qemu_loadvm_state_post_main(ret); if (mis->have_listen_thread) { - /* Listen thread still going, can't clean up yet */ + /* + * Postcopy listen thread still going, don't synchronize the + * cpus yet. + */ return ret; } @@ -3024,7 +3025,6 @@ int qemu_loadvm_state(QEMUFile *f) } } - qemu_loadvm_state_cleanup(); cpu_synchronize_all_post_init(); return ret; diff --git a/system/physmem.c b/system/physmem.c index d71a2b1bbd..dc1db3a384 100644 --- a/system/physmem.c +++ b/system/physmem.c @@ -3274,7 +3274,7 @@ void *address_space_map(AddressSpace *as, bounce->len = l; if (!is_write) { - flatview_read(fv, addr, MEMTXATTRS_UNSPECIFIED, + flatview_read(fv, addr, attrs, bounce->buffer, l); } diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c index d6768d5d71..814ec109a6 100644 --- a/tests/qtest/migration-test.c +++ b/tests/qtest/migration-test.c @@ -3803,8 +3803,10 @@ int main(int argc, char **argv) migration_test_add("/migration/precopy/unix/plain", test_precopy_unix_plain); - migration_test_add("/migration/precopy/unix/xbzrle", - test_precopy_unix_xbzrle); + if (g_test_slow()) { + migration_test_add("/migration/precopy/unix/xbzrle", + test_precopy_unix_xbzrle); + } migration_test_add("/migration/precopy/file", test_precopy_file); migration_test_add("/migration/precopy/file/offset", @@ -3979,7 +3981,7 @@ int main(int argc, char **argv) if (g_str_equal(arch, "x86_64") && has_kvm && kvm_dirty_ring_supported()) { migration_test_add("/migration/dirty_ring", test_precopy_unix_dirty_ring); - if (qtest_has_machine("pc")) { + if (qtest_has_machine("pc") && g_test_slow()) { migration_test_add("/migration/vcpu_dirty_limit", test_vcpu_dirty_limit); }