958e1b
From 20a401a160bb959469e95cc809b53609eedccb40 Mon Sep 17 00:00:00 2001
eb5a2f
From: Dr. David Alan Gilbert (git) <dgilbert@redhat.com>
eb5a2f
Date: Thu, 8 May 2014 11:27:33 +0200
958e1b
Subject: [PATCH 08/31] Count used RAMBlock pages for migration_dirty_pages
eb5a2f
eb5a2f
RH-Author: Dr. David Alan Gilbert (git) <dgilbert@redhat.com>
eb5a2f
Message-id: <1399548453-9181-2-git-send-email-dgilbert@redhat.com>
eb5a2f
Patchwork-id: 58746
eb5a2f
O-Subject: [RHEL7.1/RHEL7.0.z qemu-kvm PATCH 1/1] Count used RAMBlock pages for migration_dirty_pages
958e1b
Bugzilla: 1074913
eb5a2f
RH-Acked-by: Juan Quintela <quintela@redhat.com>
eb5a2f
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
eb5a2f
RH-Acked-by: Amit Shah <amit.shah@redhat.com>
eb5a2f
eb5a2f
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
eb5a2f
958e1b
This is a fix for a bug* triggered by a migration after hot unplugging
eb5a2f
a few virtio-net NICs, that caused migration never to converge, because
eb5a2f
'migration_dirty_pages' is incorrectly initialised.
eb5a2f
eb5a2f
'migration_dirty_pages' is used as a tally of the number of outstanding
eb5a2f
dirty pages, to give the migration code an idea of how much more data
eb5a2f
will need to be transferred, and thus whether it can end the iterative
eb5a2f
phase.
eb5a2f
eb5a2f
It was initialised to the total size of the RAMBlock address space,
eb5a2f
however hotunplug can leave this space sparse, and hence
eb5a2f
migration_dirty_pages ended up too large.
eb5a2f
eb5a2f
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
eb5a2f
958e1b
(* https://bugzilla.redhat.com/show_bug.cgi?id=1074913 )
958e1b
eb5a2f
Signed-off-by: Juan Quintela <quintela@redhat.com>
eb5a2f
(cherry picked from commit e30d1d8c7195848abb28a8c734a82b845b8b456a)
eb5a2f
---
eb5a2f
 arch_init.c | 21 +++++++++++++++++----
eb5a2f
 1 file changed, 17 insertions(+), 4 deletions(-)
eb5a2f
eb5a2f
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
eb5a2f
---
eb5a2f
 arch_init.c |   21 +++++++++++++++++----
eb5a2f
 1 files changed, 17 insertions(+), 4 deletions(-)
eb5a2f
eb5a2f
diff --git a/arch_init.c b/arch_init.c
eb5a2f
index 22f7def..b88d686 100644
eb5a2f
--- a/arch_init.c
eb5a2f
+++ b/arch_init.c
eb5a2f
@@ -728,11 +728,8 @@ static void reset_ram_globals(void)
eb5a2f
 static int ram_save_setup(QEMUFile *f, void *opaque)
eb5a2f
 {
eb5a2f
     RAMBlock *block;
eb5a2f
-    int64_t ram_pages = last_ram_offset() >> TARGET_PAGE_BITS;
eb5a2f
+    int64_t ram_bitmap_pages; /* Size of bitmap in pages, including gaps */
eb5a2f
 
eb5a2f
-    migration_bitmap = bitmap_new(ram_pages);
eb5a2f
-    bitmap_set(migration_bitmap, 0, ram_pages);
eb5a2f
-    migration_dirty_pages = ram_pages;
eb5a2f
     mig_throttle_on = false;
eb5a2f
     dirty_rate_high_cnt = 0;
eb5a2f
 
eb5a2f
@@ -771,6 +768,22 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
eb5a2f
     bytes_transferred = 0;
eb5a2f
     reset_ram_globals();
eb5a2f
 
eb5a2f
+    ram_bitmap_pages = last_ram_offset() >> TARGET_PAGE_BITS;
eb5a2f
+    migration_bitmap = bitmap_new(ram_bitmap_pages);
eb5a2f
+    bitmap_set(migration_bitmap, 0, ram_bitmap_pages);
eb5a2f
+
eb5a2f
+    /*
eb5a2f
+     * Count the total number of pages used by ram blocks not including any
eb5a2f
+     * gaps due to alignment or unplugs.
eb5a2f
+     */
eb5a2f
+    migration_dirty_pages = 0;
eb5a2f
+    QTAILQ_FOREACH(block, &ram_list.blocks, next) {
eb5a2f
+        uint64_t block_pages;
eb5a2f
+
eb5a2f
+        block_pages = block->length >> TARGET_PAGE_BITS;
eb5a2f
+        migration_dirty_pages += block_pages;
eb5a2f
+    }
eb5a2f
+
eb5a2f
     memory_global_dirty_log_start();
eb5a2f
     migration_bitmap_sync();
eb5a2f
     qemu_mutex_unlock_iothread();
eb5a2f
-- 
eb5a2f
1.7.1
eb5a2f