memory: Fix incorrect calls of log_global_start/stop

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 <huangy81@chinatelecom.cn>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Dr. David Alan Gilbert <dgilbert@redhat.com>
Cc: Juan Quintela <quintela@redhat.com>
Cc: David Hildenbrand <david@redhat.com>
Signed-off-by: Peter Xu <peterx@redhat.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Message-Id: <20211130080028.6474-1-peterx@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
This commit is contained in:
Peter Xu 2021-11-30 16:00:28 +08:00 committed by Philippe Mathieu-Daudé
parent 455faf03df
commit 7b0538ed3a

View File

@ -2794,6 +2794,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;
@ -2802,15 +2804,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);
if (!old_flags) {
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();
}
}
static void memory_global_dirty_log_do_stop(unsigned int flags)
@ -2821,12 +2822,12 @@ static void memory_global_dirty_log_do_stop(unsigned int flags)
trace_global_dirty_changed(global_dirty_tracking);
/* Refresh DIRTY_MEMORY_MIGRATION bit. */
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,