From: Prasad Pandit <p...@fedoraproject.org>

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 <p...@fedoraproject.org>
---
 migration/multifd-zero-page.c | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

v11:
- s/ones/once, remove capitalisations and call _test_byte_offset() once

v10:
- 
https://lore.kernel.org/qemu-devel/20250508122849.207213-2-ppan...@redhat.com/T/#t

diff --git a/migration/multifd-zero-page.c b/migration/multifd-zero-page.c
index dbc1184921..4cde868159 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]);
         }
     }
--
2.49.0


Reply via email to