diff options
| author | Peter Maydell <peter.maydell@linaro.org> | 2022-02-21 17:24:05 +0000 |
|---|---|---|
| committer | Peter Maydell <peter.maydell@linaro.org> | 2022-02-21 17:24:05 +0000 |
| commit | 922268067fe4181d6edcfccd689e908e4d1243ad (patch) | |
| tree | b2d27104b2a6533a8d3d02e76e8ccadf0975017a /softmmu/memory.c | |
| parent | 477c3b934a47adf7de285863f59d6e4503dd1a6d (diff) | |
| parent | 5dc4618e781f36c4bea1b0cdd1bea75b48640c5a (diff) | |
| download | focaccia-qemu-922268067fe4181d6edcfccd689e908e4d1243ad.tar.gz focaccia-qemu-922268067fe4181d6edcfccd689e908e4d1243ad.zip | |
Merge remote-tracking branch 'remotes/bonzini-gitlab/tags/for-upstream' into staging
* More Meson conversions (0.59.x now required rather than suggested) * UMIP support for TCG x86 * Fix migration crash * Restore error output for check-block # gpg: Signature made Mon 21 Feb 2022 09:35:59 GMT # gpg: using RSA key F13338574B662389866C7682BFFBD25F78C7AE83 # gpg: issuer "pbonzini@redhat.com" # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full] # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" [full] # Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1 # Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83 * remotes/bonzini-gitlab/tags/for-upstream: (29 commits) configure, meson: move CONFIG_IASL to a Meson option meson, configure: move ntddscsi API check to meson meson: require dynamic linking for VSS support qga/vss-win32: require widl/midl, remove pre-built TLB file meson: do not make qga/vss-win32/meson.build conditional on C++ presence configure, meson: replace VSS SDK checks and options with --enable-vss-sdk qga/vss: use standard windows headers location qga/vss-win32: use widl if available meson: drop --with-win-sdk qga/vss-win32: fix midl arguments meson: refine check for whether to look for virglrenderer configure, meson: move guest-agent, tools to meson configure, meson: move smbd options to meson_options.txt configure, meson: move coroutine options to meson_options.txt configure, meson: move some default-disabled options to meson_options.txt meson: define qemu_cflags/qemu_ldflags configure, meson: move block layer options to meson_options.txt configure, meson: move image format options to meson_options.txt configure, meson: cleanup qemu-ga libraries configure, meson: move TPM check to meson ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'softmmu/memory.c')
| -rw-r--r-- | softmmu/memory.c | 61 |
1 files changed, 45 insertions, 16 deletions
diff --git a/softmmu/memory.c b/softmmu/memory.c index 678dc62f06..8060c6de78 100644 --- a/softmmu/memory.c +++ b/softmmu/memory.c @@ -2790,19 +2790,32 @@ void memory_global_after_dirty_log_sync(void) MEMORY_LISTENER_CALL_GLOBAL(log_global_after_sync, Forward); } +/* + * Dirty track stop flags that are postponed due to VM being stopped. Should + * only be used within vmstate_change hook. + */ +static unsigned int postponed_stop_flags; static VMChangeStateEntry *vmstate_change; +static void memory_global_dirty_log_stop_postponed_run(void); void memory_global_dirty_log_start(unsigned int flags) { - unsigned int old_flags = global_dirty_tracking; + unsigned int old_flags; + + assert(flags && !(flags & (~GLOBAL_DIRTY_MASK))); if (vmstate_change) { - qemu_del_vm_change_state_handler(vmstate_change); - vmstate_change = NULL; + /* If there is postponed stop(), operate on it first */ + postponed_stop_flags &= ~flags; + memory_global_dirty_log_stop_postponed_run(); } - assert(flags && !(flags & (~GLOBAL_DIRTY_MASK))); - assert(!(global_dirty_tracking & flags)); + flags &= ~global_dirty_tracking; + if (!flags) { + return; + } + + old_flags = global_dirty_tracking; global_dirty_tracking |= flags; trace_global_dirty_changed(global_dirty_tracking); @@ -2830,29 +2843,45 @@ static void memory_global_dirty_log_do_stop(unsigned int flags) } } +/* + * Execute the postponed dirty log stop operations if there is, then reset + * everything (including the flags and the vmstate change hook). + */ +static void memory_global_dirty_log_stop_postponed_run(void) +{ + /* This must be called with the vmstate handler registered */ + assert(vmstate_change); + + /* Note: postponed_stop_flags can be cleared in log start routine */ + if (postponed_stop_flags) { + memory_global_dirty_log_do_stop(postponed_stop_flags); + postponed_stop_flags = 0; + } + + qemu_del_vm_change_state_handler(vmstate_change); + vmstate_change = NULL; +} + static void memory_vm_change_state_handler(void *opaque, bool running, RunState state) { - unsigned int flags = (unsigned int)(uintptr_t)opaque; if (running) { - memory_global_dirty_log_do_stop(flags); - - if (vmstate_change) { - qemu_del_vm_change_state_handler(vmstate_change); - vmstate_change = NULL; - } + memory_global_dirty_log_stop_postponed_run(); } } void memory_global_dirty_log_stop(unsigned int flags) { if (!runstate_is_running()) { + /* Postpone the dirty log stop, e.g., to when VM starts again */ if (vmstate_change) { - return; + /* Batch with previous postponed flags */ + postponed_stop_flags |= flags; + } else { + postponed_stop_flags = flags; + vmstate_change = qemu_add_vm_change_state_handler( + memory_vm_change_state_handler, NULL); } - vmstate_change = qemu_add_vm_change_state_handler( - memory_vm_change_state_handler, - (void *)(uintptr_t)flags); return; } |