2 * Multifd zero page detection implementation.
4 * Copyright (c) 2024 Bytedance Inc
7 * Hao Xiang <hao.xiang@bytedance.com>
9 * This work is licensed under the terms of the GNU GPL, version 2 or later.
10 * See the COPYING file in the top-level directory.
13 #include "qemu/osdep.h"
14 #include "qemu/cutils.h"
15 #include "exec/ramblock.h"
16 #include "migration.h"
21 static bool multifd_zero_page_enabled(void)
23 return migrate_zero_page_detection() == ZERO_PAGE_DETECTION_MULTIFD
;
26 static void swap_page_offset(ram_addr_t
*pages_offset
, int a
, int b
)
34 temp
= pages_offset
[a
];
35 pages_offset
[a
] = pages_offset
[b
];
36 pages_offset
[b
] = temp
;
40 * multifd_send_zero_page_detect: Perform zero page detection on all pages.
42 * Sorts normal pages before zero pages in p->pages->offset and updates
43 * p->pages->normal_num.
45 * @param p A pointer to the send params.
47 void multifd_send_zero_page_detect(MultiFDSendParams
*p
)
49 MultiFDPages_t
*pages
= p
->pages
;
50 RAMBlock
*rb
= pages
->block
;
52 int j
= pages
->num
- 1;
54 if (!multifd_zero_page_enabled()) {
55 pages
->normal_num
= pages
->num
;
60 * Sort the page offset array by moving all normal pages to
61 * the left and all zero pages to the right of the array.
64 uint64_t offset
= pages
->offset
[i
];
66 if (!buffer_is_zero(rb
->host
+ offset
, p
->page_size
)) {
71 swap_page_offset(pages
->offset
, i
, j
);
72 ram_release_page(rb
->idstr
, offset
);
76 pages
->normal_num
= i
;
79 void multifd_recv_zero_page_process(MultiFDRecvParams
*p
)
81 for (int i
= 0; i
< p
->zero_num
; i
++) {
82 void *page
= p
->host
+ p
->zero
[i
];
83 if (ramblock_recv_bitmap_test_byte_offset(p
->block
, p
->zero
[i
])) {
84 memset(page
, 0, p
->page_size
);
86 ramblock_recv_bitmap_set_offset(p
->block
, p
->zero
[i
]);