From b169059c8fbf15c3ffeec0f68b938cb9febd8db7 Mon Sep 17 00:00:00 2001 From: Peter Xu Date: Tue, 30 Nov 2021 16:00:28 +0800 Subject: [PATCH 5/6] memory: Fix incorrect calls of log_global_start/stop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RH-Author: Peter Xu RH-MergeRequest: 77: memory: Fix qemu crash on continuous migrations of stopped VM RH-Commit: [1/2] 6271ee689266b24d29d4c87f60e5b096ef5f5d63 (peterx/qemu-kvm) RH-Bugzilla: 2044818 RH-Acked-by: Paolo Bonzini RH-Acked-by: David Hildenbrand RH-Acked-by: quintela1 We should only call the log_global_start/stop when the global dirty track bitmask changes from zero<->non-zero. No real issue reported for this yet probably because no immediate user to enable both dirty rate measurement and migration at the same time. However it'll be good to be prepared for it. Fixes: 63b41db4bc ("memory: make global_dirty_tracking a bitmask") Cc: qemu-stable@nongnu.org Cc: Hyman Huang Cc: Paolo Bonzini Cc: Dr. David Alan Gilbert Cc: Juan Quintela Cc: David Hildenbrand Signed-off-by: Peter Xu Reviewed-by: David Hildenbrand Message-Id: <20211130080028.6474-1-peterx@redhat.com> Signed-off-by: Philippe Mathieu-Daudé (cherry picked from commit 7b0538ed3a22ce30817f818449d10701fb0821f9) Signed-off-by: Peter Xu --- softmmu/memory.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/softmmu/memory.c b/softmmu/memory.c index 7340e19ff5..81d4bf1454 100644 --- a/softmmu/memory.c +++ b/softmmu/memory.c @@ -2773,6 +2773,8 @@ static VMChangeStateEntry *vmstate_change; void memory_global_dirty_log_start(unsigned int flags) { + unsigned int old_flags = global_dirty_tracking; + if (vmstate_change) { qemu_del_vm_change_state_handler(vmstate_change); vmstate_change = NULL; @@ -2781,15 +2783,14 @@ void memory_global_dirty_log_start(unsigned int flags) assert(flags && !(flags & (~GLOBAL_DIRTY_MASK))); assert(!(global_dirty_tracking & flags)); global_dirty_tracking |= flags; - trace_global_dirty_changed(global_dirty_tracking); - MEMORY_LISTENER_CALL_GLOBAL(log_global_start, Forward); - - /* Refresh DIRTY_MEMORY_MIGRATION bit. */ - memory_region_transaction_begin(); - memory_region_update_pending = true; - memory_region_transaction_commit(); + if (!old_flags) { + MEMORY_LISTENER_CALL_GLOBAL(log_global_start, Forward); + memory_region_transaction_begin(); + memory_region_update_pending = true; + memory_region_transaction_commit(); + } } static void memory_global_dirty_log_do_stop(unsigned int flags) @@ -2800,12 +2801,12 @@ static void memory_global_dirty_log_do_stop(unsigned int flags) trace_global_dirty_changed(global_dirty_tracking); - /* Refresh DIRTY_MEMORY_MIGRATION bit. */ - memory_region_transaction_begin(); - memory_region_update_pending = true; - memory_region_transaction_commit(); - - MEMORY_LISTENER_CALL_GLOBAL(log_global_stop, Reverse); + if (!global_dirty_tracking) { + memory_region_transaction_begin(); + memory_region_update_pending = true; + memory_region_transaction_commit(); + MEMORY_LISTENER_CALL_GLOBAL(log_global_stop, Reverse); + } } static void memory_vm_change_state_handler(void *opaque, bool running, -- 2.27.0