From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43872) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1boW9k-0005aQ-3T for qemu-devel@nongnu.org; Mon, 26 Sep 2016 09:41:20 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1boW9h-0004jg-PF for qemu-devel@nongnu.org; Mon, 26 Sep 2016 09:41:15 -0400 Received: from mx1.redhat.com ([209.132.183.28]:35530) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1boW9h-0004jU-F9 for qemu-devel@nongnu.org; Mon, 26 Sep 2016 09:41:13 -0400 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id F10656A6B4 for ; Mon, 26 Sep 2016 13:41:12 +0000 (UTC) Received: from donizetti.redhat.com (ovpn-112-31.ams2.redhat.com [10.36.112.31]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u8QDexdv009350 for ; Mon, 26 Sep 2016 09:41:11 -0400 From: Paolo Bonzini Date: Mon, 26 Sep 2016 15:40:37 +0200 Message-Id: <1474897258-1205-8-git-send-email-pbonzini@redhat.com> In-Reply-To: <1474897258-1205-1-git-send-email-pbonzini@redhat.com> References: <1474897258-1205-1-git-send-email-pbonzini@redhat.com> Subject: [Qemu-devel] [PULL 07/28] migration: sync all address spaces List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Migrating a VM during reboot sometimes results in differences between the source and destination in the SMRAM area. This is because migration_bitmap_sync() only fetches from KVM the dirty log of address_space_memory. SMRAM memory slots are ignored and the modifications to SMRAM are not sent to the destination. Reported-by: He Rongguang Reviewed-by: He Rongguang Signed-off-by: Paolo Bonzini --- include/exec/memory.h | 7 +++---- memory.c | 46 +++++++++++++++++++++++++++++++++------------- migration/ram.c | 2 +- 3 files changed, 37 insertions(+), 18 deletions(-) diff --git a/include/exec/memory.h b/include/exec/memory.h index a3f988b..10d7eac 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -1188,12 +1188,11 @@ MemoryRegionSection memory_region_find(MemoryRegion *mr, hwaddr addr, uint64_t size); /** - * address_space_sync_dirty_bitmap: synchronize the dirty log for all memory + * memory_global_dirty_log_sync: synchronize the dirty log for all memory * - * Synchronizes the dirty page log for an entire address space. - * @as: the address space that contains the memory being synchronized + * Synchronizes the dirty page log for all address spaces. */ -void address_space_sync_dirty_bitmap(AddressSpace *as); +void memory_global_dirty_log_sync(void); /** * memory_region_transaction_begin: Start a transaction. diff --git a/memory.c b/memory.c index 27a3f2f..58f9269 100644 --- a/memory.c +++ b/memory.c @@ -158,14 +158,10 @@ static bool memory_listener_match(MemoryListener *listener, /* No need to ref/unref .mr, the FlatRange keeps it alive. */ #define MEMORY_LISTENER_UPDATE_REGION(fr, as, dir, callback, _args...) \ - MEMORY_LISTENER_CALL(callback, dir, (&(MemoryRegionSection) { \ - .mr = (fr)->mr, \ - .address_space = (as), \ - .offset_within_region = (fr)->offset_in_region, \ - .size = (fr)->addr.size, \ - .offset_within_address_space = int128_get64((fr)->addr.start), \ - .readonly = (fr)->readonly, \ - }), ##_args) + do { \ + MemoryRegionSection mrs = section_from_flat_range(fr, as); \ + MEMORY_LISTENER_CALL(callback, dir, &mrs, ##_args); \ + } while(0) struct CoalescedMemoryRange { AddrRange addr; @@ -245,6 +241,19 @@ typedef struct AddressSpaceOps AddressSpaceOps; #define FOR_EACH_FLAT_RANGE(var, view) \ for (var = (view)->ranges; var < (view)->ranges + (view)->nr; ++var) +static inline MemoryRegionSection +section_from_flat_range(FlatRange *fr, AddressSpace *as) +{ + return (MemoryRegionSection) { + .mr = fr->mr, + .address_space = as, + .offset_within_region = fr->offset_in_region, + .size = fr->addr.size, + .offset_within_address_space = int128_get64(fr->addr.start), + .readonly = fr->readonly, + }; +} + static bool flatrange_equal(FlatRange *a, FlatRange *b) { return a->mr == b->mr @@ -2156,16 +2165,27 @@ bool memory_region_present(MemoryRegion *container, hwaddr addr) return mr && mr != container; } -void address_space_sync_dirty_bitmap(AddressSpace *as) +void memory_global_dirty_log_sync(void) { + MemoryListener *listener; + AddressSpace *as; FlatView *view; FlatRange *fr; - view = address_space_get_flatview(as); - FOR_EACH_FLAT_RANGE(fr, view) { - MEMORY_LISTENER_UPDATE_REGION(fr, as, Forward, log_sync); + QTAILQ_FOREACH(listener, &memory_listeners, link) { + if (!listener->log_sync) { + continue; + } + /* Global listeners are being phased out. */ + assert(listener->address_space_filter); + as = listener->address_space_filter; + view = address_space_get_flatview(as); + FOR_EACH_FLAT_RANGE(fr, view) { + MemoryRegionSection mrs = section_from_flat_range(fr, as); + listener->log_sync(listener, &mrs); + } + flatview_unref(view); } - flatview_unref(view); } void memory_global_dirty_log_start(void) diff --git a/migration/ram.c b/migration/ram.c index a6e1c63..c8ec9f2 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -626,7 +626,7 @@ static void migration_bitmap_sync(void) } trace_migration_bitmap_sync_start(); - address_space_sync_dirty_bitmap(&address_space_memory); + memory_global_dirty_log_sync(); qemu_mutex_lock(&migration_bitmap_mutex); rcu_read_lock(); -- 2.7.4