@@ -274,3 +274,37 @@ void qemu_balloon_bitmap_reset(bool source)
}
balloon_bitmap_state = BALLOON_BITMAP_INIT;
}
+
+int qemu_balloon_bitmap_test(RAMBlock *rb, ram_addr_t addr)
+{
+ ram_addr_t base;
+ unsigned long nr = 0;
+ int i = 0, count = 0, loop = 0;
+ int ret = 0;
+
+ if (balloon_bitmap_state != BALLOON_BITMAP_ENABLE) {
+ return 0;
+ }
+
+ base = rb->offset >> balloon_bitmap_pfn_shift;
+ nr = base + (addr >> balloon_bitmap_pfn_shift);
+
+ qemu_mutex_lock_balloon_bitmap();
+ if (TARGET_PAGE_BITS <= balloon_bitmap_pfn_shift) {
+ ret = (test_bit(nr, bmap)) ? 1 : 0;
+ } else {
+ loop = (1UL << (TARGET_PAGE_BITS - balloon_bitmap_pfn_shift));
+ for (i = 0; i < loop; i++) {
+ if (test_bit((nr + i), bmap)) {
+ count++;
+ }
+ }
+ /* addr is alligned to TARGET_PAGE_SIZE, return true only if all
+ * sub-pages (1 << balloon_bitmap_pfn_shift or 4K) are ballooned out.
+ */
+ ret = (count == loop) ? 1 : 0;
+ }
+ qemu_mutex_unlock_balloon_bitmap();
+
+ return ret;
+}
@@ -34,5 +34,6 @@ void qemu_balloon_bitmap_extend(RAMBlock *new_block,
ram_addr_t old, ram_addr_t new);
void qemu_balloon_bitmap_setup(void);
void qemu_balloon_bitmap_reset(bool source);
+int qemu_balloon_bitmap_test(RAMBlock *rb, ram_addr_t addr);
#endif
@@ -704,6 +704,10 @@ static int save_zero_page(QEMUFile *f, RAMBlock *block, ram_addr_t offset,
{
int pages = -1;
+ if (qemu_balloon_bitmap_test(block, offset) == 1) {
+ return 0; /* pages */
+ }
+
if (is_zero_range(p, TARGET_PAGE_SIZE)) {
acct_info.dup_pages++;
*bytes_transferred += save_page_header(f, block,
@@ -770,7 +774,7 @@ static int ram_save_page(QEMUFile *f, PageSearchStatus *pss,
}
} else {
pages = save_zero_page(f, block, offset, p, bytes_transferred);
- if (pages > 0) {
+ if (pages >= 0) {
/* Must let xbzrle know, otherwise a previous (now 0'd) cached
* page would be stale
*/
During live migration, byte offset within memory region of the start of a dirty page is checked against the balloon bitmap, if the bit is set in the balloon bitmap, the corresponding ram page will be excluded from scanning and sending header information during migration. In case TARGET_PAGE_BITS > VIRTIO_BALLOON_PFN_SHIFT, the bitmap test function will return true if all sub-pages of size (1UL << VIRTIO_BALLOON_PFN_SHIFT) within dirty page are ballooned out. The test against bitmap gets disabled in case balloon bitmap status is set to disable during migration setup. Signed-off-by: Jitendra Kolhe <jitendra.kolhe@hpe.com> --- balloon.c | 34 ++++++++++++++++++++++++++++++++++ include/sysemu/balloon.h | 1 + migration/ram.c | 6 +++++- 3 files changed, 40 insertions(+), 1 deletion(-)