diff mbox

[v3,4/4] migration: skip scanning and migrating ram pages released by virtio-balloon driver.

Message ID 1463570532-29862-1-git-send-email-jitendra.kolhe@hpe.com
State New
Headers show

Commit Message

Jitendra Kolhe May 18, 2016, 11:22 a.m. UTC
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(-)
diff mbox

Patch

diff --git a/balloon.c b/balloon.c
index 494b8aa..baa7e5a 100644
--- a/balloon.c
+++ b/balloon.c
@@ -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;
+}
diff --git a/include/sysemu/balloon.h b/include/sysemu/balloon.h
index 9a9bed9..941982e 100644
--- a/include/sysemu/balloon.h
+++ b/include/sysemu/balloon.h
@@ -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
diff --git a/migration/ram.c b/migration/ram.c
index a4c3582..a5802d9 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -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
              */