All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v3 1/1] Count used RAMBlock pages for migration_dirty_pages
@ 2014-03-21 19:40 Dr. David Alan Gilbert (git)
  0 siblings, 0 replies; only message in thread
From: Dr. David Alan Gilbert (git) @ 2014-03-21 19:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, quintela

From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>

This is a fix for a bug* triggered by a migration after hot unplugging
a few virtio-net NICs, that caused migration never to converge, because
'migration_dirty_pages' is incorrectly initialised.

'migration_dirty_pages' is used as a tally of the number of outstanding
dirty pages, to give the migration code an idea of how much more data
will need to be transferred, and thus whether it can end the iterative
phase.

It was initialised to the total size of the RAMBlock address space,
however hotunplug can leave this space sparse, and hence
migration_dirty_pages ended up too large.

Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>

(* https://bugzilla.redhat.com/show_bug.cgi?id=1074913 )
---
 arch_init.c | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

v3:
   Commit message only; fix up stupid copy-and-paste

v2:
   Don't worry about RAMBlocks sharing a page; it doesn't happen

diff --git a/arch_init.c b/arch_init.c
index f18f42e..47a1e44 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -727,11 +727,8 @@ static void reset_ram_globals(void)
 static int ram_save_setup(QEMUFile *f, void *opaque)
 {
     RAMBlock *block;
-    int64_t ram_pages = last_ram_offset() >> TARGET_PAGE_BITS;
+    int64_t ram_bitmap_pages; /* Size of bitmap in pages, including gaps */
 
-    migration_bitmap = bitmap_new(ram_pages);
-    bitmap_set(migration_bitmap, 0, ram_pages);
-    migration_dirty_pages = ram_pages;
     mig_throttle_on = false;
     dirty_rate_high_cnt = 0;
 
@@ -770,6 +767,22 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
     bytes_transferred = 0;
     reset_ram_globals();
 
+    ram_bitmap_pages = last_ram_offset() >> TARGET_PAGE_BITS;
+    migration_bitmap = bitmap_new(ram_bitmap_pages);
+    bitmap_set(migration_bitmap, 0, ram_bitmap_pages);
+
+    /*
+     * Count the total number of pages used by ram blocks not including any
+     * gaps due to alignment or unplugs.
+     */
+    migration_dirty_pages = 0;
+    QTAILQ_FOREACH(block, &ram_list.blocks, next) {
+        uint64_t block_pages = 0;
+
+        block_pages = (block->length + TARGET_PAGE_SIZE - 1) / TARGET_PAGE_SIZE;
+        migration_dirty_pages += block_pages;
+    }
+
     memory_global_dirty_log_start();
     migration_bitmap_sync();
     qemu_mutex_unlock_iothread();
-- 
1.8.5.3

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2014-03-21 19:40 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-03-21 19:40 [Qemu-devel] [PATCH v3 1/1] Count used RAMBlock pages for migration_dirty_pages Dr. David Alan Gilbert (git)

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.