From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40547) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YbBkg-0006DL-IU for qemu-devel@nongnu.org; Thu, 26 Mar 2015 13:39:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YbBkb-0003iz-Qe for qemu-devel@nongnu.org; Thu, 26 Mar 2015 13:39:30 -0400 Received: from mx1.redhat.com ([209.132.183.28]:43906) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YbBkb-0003il-Ir for qemu-devel@nongnu.org; Thu, 26 Mar 2015 13:39:25 -0400 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 3BBEFB6F2F for ; Thu, 26 Mar 2015 17:39:25 +0000 (UTC) Received: from donizetti.redhat.com (ovpn-112-86.ams2.redhat.com [10.36.112.86]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t2QHcflS025898 for ; Thu, 26 Mar 2015 13:39:23 -0400 From: Paolo Bonzini Date: Thu, 26 Mar 2015 18:38:40 +0100 Message-Id: <1427391520-29497-23-git-send-email-pbonzini@redhat.com> In-Reply-To: <1427391520-29497-1-git-send-email-pbonzini@redhat.com> References: <1427391520-29497-1-git-send-email-pbonzini@redhat.com> Subject: [Qemu-devel] [PATCH 22/22] migration: run bitmap sync outside iothread lock List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org 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 --- 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