aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPrasad Pandit <pjp@fedoraproject.org>2025-05-12 18:21:22 +0530
committerPeter Xu <peterx@redhat.com>2025-05-20 11:26:32 -0400
commit249543d0c02d7645b8bcda552dad138769e96831 (patch)
treeed88451ccd81582a91b1cca2147d640568fa44f5
parent371650534d44c8b27249ca615d908a037f75b048 (diff)
downloadqemu-249543d0c02d7645b8bcda552dad138769e96831.zip
qemu-249543d0c02d7645b8bcda552dad138769e96831.tar.gz
qemu-249543d0c02d7645b8bcda552dad138769e96831.tar.bz2
migration: write zero pages when postcopy enabled
During multifd migration, zero pages are written if they are migrated more than once. This may result in a migration thread hang issue when multifd and postcopy are enabled together. When postcopy is enabled, always write zero pages as and when they are migrated. Signed-off-by: Prasad Pandit <pjp@fedoraproject.org> Reviewed-by: Fabiano Rosas <farosas@suse.de> Link: https://lore.kernel.org/r/20250512125124.147064-2-ppandit@redhat.com Signed-off-by: Peter Xu <peterx@redhat.com>
-rw-r--r--migration/multifd-zero-page.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/migration/multifd-zero-page.c b/migration/multifd-zero-page.c
index dbc1184..4cde868 100644
--- a/migration/multifd-zero-page.c
+++ b/migration/multifd-zero-page.c
@@ -85,9 +85,27 @@ void multifd_recv_zero_page_process(MultiFDRecvParams *p)
{
for (int i = 0; i < p->zero_num; i++) {
void *page = p->host + p->zero[i];
- if (ramblock_recv_bitmap_test_byte_offset(p->block, p->zero[i])) {
+ bool received =
+ ramblock_recv_bitmap_test_byte_offset(p->block, p->zero[i]);
+
+ /*
+ * During multifd migration zero page is written to the memory
+ * only if it is migrated more than once.
+ *
+ * It becomes a problem when both multifd & postcopy options are
+ * enabled. If the zero page which was skipped during multifd phase,
+ * is accessed during the postcopy phase of the migration, a page
+ * fault occurs. But this page fault is not served because the
+ * 'receivedmap' says the zero page is already received. Thus the
+ * thread accessing that page may hang.
+ *
+ * When postcopy is enabled, always write the zero page as and when
+ * it is migrated.
+ */
+ if (migrate_postcopy_ram() || received) {
memset(page, 0, multifd_ram_page_size());
- } else {
+ }
+ if (!received) {
ramblock_recv_bitmap_set_offset(p->block, p->zero[i]);
}
}