qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 22/22] migration: run bitmap sync outside iothread l


From: Paolo Bonzini
Subject: [Qemu-devel] [PATCH 22/22] migration: run bitmap sync outside iothread lock
Date: Thu, 26 Mar 2015 18:38:40 +0100

Synchronization of the dirty bitmap can now run concurrently
with modifications of it.

Note that the change in migration_bitmap_sync is not needed
and is only for improved clarity.

Signed-off-by: Paolo Bonzini <address@hidden>
---
 arch_init.c           | 10 +++++-----
 include/exec/memory.h |  8 ++++++++
 2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/arch_init.c b/arch_init.c
index 75bba49..3ac63c6 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -512,10 +512,10 @@ static void migration_bitmap_sync(void)
         start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
     }
 
+    rcu_read_lock();
     trace_migration_bitmap_sync_start();
     address_space_sync_dirty_bitmap(&address_space_memory);
 
-    rcu_read_lock();
     QLIST_FOREACH_RCU(block, &ram_list.blocks, next) {
         migration_bitmap_sync_range(block->mr->ram_addr, block->used_length);
     }
@@ -838,7 +838,9 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
         acct_clear();
     }
 
-    /* iothread lock needed for ram_list.dirty_memory[] */
+    /* iothread lock needed for ram_list.dirty_memory[],
+     * ramlist lock needed for memory_global_dirty_log_start().
+     */
     qemu_mutex_lock_iothread();
     qemu_mutex_lock_ramlist();
     rcu_read_lock();
@@ -856,10 +858,10 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
     migration_dirty_pages = ram_bytes_total() >> TARGET_PAGE_BITS;
 
     memory_global_dirty_log_start();
-    migration_bitmap_sync();
     qemu_mutex_unlock_ramlist();
     qemu_mutex_unlock_iothread();
 
+    migration_bitmap_sync();
     qemu_put_be64(f, ram_bytes_total() | RAM_SAVE_FLAG_MEM_SIZE);
 
     QLIST_FOREACH_RCU(block, &ram_list.blocks, next) {
@@ -980,11 +982,9 @@ static uint64_t ram_save_pending(QEMUFile *f, void 
*opaque, uint64_t max_size)
     remaining_size = ram_save_remaining() * TARGET_PAGE_SIZE;
 
     if (remaining_size < max_size) {
-        qemu_mutex_lock_iothread();
         rcu_read_lock();
         migration_bitmap_sync();
         rcu_read_unlock();
-        qemu_mutex_unlock_iothread();
         remaining_size = ram_save_remaining() * TARGET_PAGE_SIZE;
     }
     return remaining_size;
diff --git a/include/exec/memory.h b/include/exec/memory.h
index aa46a52..e79e2d5 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -177,6 +177,9 @@ struct MemoryRegion {
  *
  * Allows a component to adjust to changes in the guest-visible memory map.
  * Use with memory_listener_register() and memory_listener_unregister().
+ *
+ * All functions called while holding the iothread lock, EXCEPT FOR log_sync
+ * which may be called either with or without the iothread lock held.
  */
 struct MemoryListener {
     void (*begin)(MemoryListener *listener);
@@ -682,6 +685,9 @@ bool memory_region_test_and_clear_dirty(MemoryRegion *mr, 
hwaddr addr,
  * Flushes dirty information from accelerators such as kvm and vhost-net
  * and makes it available to users of the memory API.
  *
+ * Unlike other memory region function, memory_region_sync_dirty_bitmap
+ * may be called either with or without the iothread lock held.
+ *
  * @mr: the region being flushed.
  */
 void memory_region_sync_dirty_bitmap(MemoryRegion *mr);
@@ -994,6 +1000,8 @@ MemoryRegionSection memory_region_find(MemoryRegion *mr,
  * address_space_sync_dirty_bitmap: synchronize the dirty log for all memory
  *
  * Synchronizes the dirty page log for an entire address space.
+ * May be called either with or without the iothread lock held.
+ *
  * @as: the address space that contains the memory being synchronized
  */
 void address_space_sync_dirty_bitmap(AddressSpace *as);
-- 
2.3.3




reply via email to

[Prev in Thread] Current Thread [Next in Thread]