diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2023-06-01 20:59:28 -0700 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2023-06-01 20:59:28 -0700 |
commit | a86d7b9ec0adb2f1efce8ab30d9ed2b72db0236e (patch) | |
tree | 7c91e7b712aab60cdf08bb7516b05036671ff192 | |
parent | 9eb400cdd7b0940bd696aa01462dd53004ae04e9 (diff) | |
parent | 3a8b81f2e6393828589699bb0b8ef557b9ae5937 (diff) |
Merge tag 'migration-20230601-pull-request' of https://gitlab.com/juan.quintela/qemu into staging
Migration Pull request (20230601)
Hi
In this series:
- improve background migration (fiona)
- improve vmstate failure states (vladimir)
- dropped all the RDMA cleanups
Please, apply.
# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCAAdFiEEGJn/jt6/WMzuA0uC9IfvGFhy1yMFAmR5LAoACgkQ9IfvGFhy
# 1yPOuxAA5QzUfswCIWehrkY8FApDjsecPDq5R6hS1p5pDZkHTF5y6j49J93I65o2
# E4qr4l0+DJvBvnxTW29JQ1i0RPqJHnJBFC9Ib4o0NaA/7iRP1sTwYxIN4wWZz6H/
# pqG3oQC0WPPqgj9tHSgDW4TNkFjETYaezTN8nddNmyiaO9UxNuR5ZKbeYMroVlfp
# KbnAYfXV6CyXKUZFT32BYcajYBDZAqBCO6y3gEn77KPlT1/TqnucoYEVuNudq5SE
# jeCamTzoAQ6SIRFM/eY+aASxdsSryqDS/WLqBFsleXs1kkJ6mkDnNels4HqS+xs9
# p2Vhv/59ktoC57XsRgTgzEklAaSHunZivcQkc5szyGVE5TZyKtWg8WhA6rvlqbjK
# lb3kKpvtVi73+pAWU0hhKFdnCrB6ieCHI70CJ5mpiIu3MzLUyrNJOK4FoKNoJDOD
# Dp45DK+W/EMg51pXyHJZZqHM1p0GGj0fmhv5T05nJ590fIWV4iqDdHFxsMZ9vEPN
# iEvAB7/pXz+yECznDFrp2e047rshOGaKKNSW3zl3/7D32Ds2FKur76dL4BoymztW
# HHLxmRWn8HmHMoKYLoawWVmCBsDqy8BFct+rHbA6h/0nSCPYIUCmMrSYVqajUbXD
# Ulkh4KNQGoBCzp5Toa0dYEXVc891wVOw4k8PTARwf2OYskSkT88=
# =Km5X
# -----END PGP SIGNATURE-----
# gpg: Signature made Thu 01 Jun 2023 04:38:50 PM PDT
# gpg: using RSA key 1899FF8EDEBF58CCEE034B82F487EF185872D723
# gpg: Good signature from "Juan Quintela <quintela@redhat.com>" [unknown]
# gpg: aka "Juan Quintela <quintela@trasno.org>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg: There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 1899 FF8E DEBF 58CC EE03 4B82 F487 EF18 5872 D723
* tag 'migration-20230601-pull-request' of https://gitlab.com/juan.quintela/qemu:
migration: stop tracking ram writes when cancelling background migration
migration: restore vmstate on migration failure
migration: switch from .vm_was_running to .vm_old_state
runstate: drop unused runstate_store()
migration: never fail in global_state_store()
runstate: add runstate_get()
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
-rw-r--r-- | include/migration/global_state.h | 2 | ||||
-rw-r--r-- | include/sysemu/runstate.h | 2 | ||||
-rw-r--r-- | migration/global_state.c | 23 | ||||
-rw-r--r-- | migration/migration.c | 70 | ||||
-rw-r--r-- | migration/migration.h | 9 | ||||
-rw-r--r-- | migration/savevm.c | 6 | ||||
-rw-r--r-- | softmmu/runstate.c | 25 |
7 files changed, 66 insertions, 71 deletions
diff --git a/include/migration/global_state.h b/include/migration/global_state.h index 945eb35d5b..d7c2cd3216 100644 --- a/include/migration/global_state.h +++ b/include/migration/global_state.h @@ -16,7 +16,7 @@ #include "qapi/qapi-types-run-state.h" void register_global_state(void); -int global_state_store(void); +void global_state_store(void); void global_state_store_running(void); bool global_state_received(void); RunState global_state_get_runstate(void); diff --git a/include/sysemu/runstate.h b/include/sysemu/runstate.h index f3ed52548e..7beb29c2e2 100644 --- a/include/sysemu/runstate.h +++ b/include/sysemu/runstate.h @@ -6,9 +6,9 @@ bool runstate_check(RunState state); void runstate_set(RunState new_state); +RunState runstate_get(void); bool runstate_is_running(void); bool runstate_needs_reset(void); -bool runstate_store(char *str, size_t size); typedef void VMChangeStateHandler(void *opaque, bool running, RunState state); diff --git a/migration/global_state.c b/migration/global_state.c index a33947ca32..4e2a9d8ec0 100644 --- a/migration/global_state.c +++ b/migration/global_state.c @@ -29,23 +29,22 @@ typedef struct { static GlobalState global_state; -int global_state_store(void) +static void global_state_do_store(RunState state) { - if (!runstate_store((char *)global_state.runstate, - sizeof(global_state.runstate))) { - error_report("runstate name too big: %s", global_state.runstate); - trace_migrate_state_too_big(); - return -EINVAL; - } - return 0; + const char *state_str = RunState_str(state); + assert(strlen(state_str) < sizeof(global_state.runstate)); + strpadcpy((char *)global_state.runstate, sizeof(global_state.runstate), + state_str, '\0'); +} + +void global_state_store(void) +{ + global_state_do_store(runstate_get()); } void global_state_store_running(void) { - const char *state = RunState_str(RUN_STATE_RUNNING); - assert(strlen(state) < sizeof(global_state.runstate)); - strpadcpy((char *)global_state.runstate, sizeof(global_state.runstate), - state, '\0'); + global_state_do_store(RUN_STATE_RUNNING); } bool global_state_received(void) diff --git a/migration/migration.c b/migration/migration.c index 5de7f734b9..dc05c6f6ea 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -1402,7 +1402,7 @@ void migrate_init(MigrationState *s) s->start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME); s->total_time = 0; - s->vm_was_running = false; + s->vm_old_state = -1; s->iteration_initial_bytes = 0; s->threshold_size = 0; } @@ -2287,28 +2287,28 @@ static void migration_completion(MigrationState *s) qemu_mutex_lock_iothread(); s->downtime_start = qemu_clock_get_ms(QEMU_CLOCK_REALTIME); qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, NULL); - s->vm_was_running = runstate_is_running(); - ret = global_state_store(); - - if (!ret) { - ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE); - trace_migration_completion_vm_stop(ret); - if (ret >= 0) { - ret = migration_maybe_pause(s, ¤t_active_state, - MIGRATION_STATUS_DEVICE); - } - if (ret >= 0) { - /* - * Inactivate disks except in COLO, and track that we - * have done so in order to remember to reactivate - * them if migration fails or is cancelled. - */ - s->block_inactive = !migrate_colo(); - migration_rate_set(RATE_LIMIT_DISABLED); - ret = qemu_savevm_state_complete_precopy(s->to_dst_file, false, - s->block_inactive); - } + + s->vm_old_state = runstate_get(); + global_state_store(); + + ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE); + trace_migration_completion_vm_stop(ret); + if (ret >= 0) { + ret = migration_maybe_pause(s, ¤t_active_state, + MIGRATION_STATUS_DEVICE); + } + if (ret >= 0) { + /* + * Inactivate disks except in COLO, and track that we + * have done so in order to remember to reactivate + * them if migration fails or is cancelled. + */ + s->block_inactive = !migrate_colo(); + migration_rate_set(RATE_LIMIT_DISABLED); + ret = qemu_savevm_state_complete_precopy(s->to_dst_file, false, + s->block_inactive); } + qemu_mutex_unlock_iothread(); if (ret < 0) { @@ -2400,13 +2400,6 @@ static void bg_migration_completion(MigrationState *s) { int current_active_state = s->state; - /* - * Stop tracking RAM writes - un-protect memory, un-register UFFD - * memory ranges, flush kernel wait queues and wake up threads - * waiting for write fault to be resolved. - */ - ram_write_tracking_stop(); - if (s->state == MIGRATION_STATUS_ACTIVE) { /* * By this moment we have RAM content saved into the migration stream. @@ -2761,18 +2754,18 @@ static void migration_iteration_finish(MigrationState *s) case MIGRATION_STATUS_COLO: assert(migrate_colo()); migrate_start_colo_process(s); - s->vm_was_running = true; + s->vm_old_state = RUN_STATE_RUNNING; /* Fallthrough */ case MIGRATION_STATUS_FAILED: case MIGRATION_STATUS_CANCELLED: case MIGRATION_STATUS_CANCELLING: - if (s->vm_was_running) { + if (s->vm_old_state == RUN_STATE_RUNNING) { if (!runstate_check(RUN_STATE_SHUTDOWN)) { vm_start(); } } else { if (runstate_check(RUN_STATE_FINISH_MIGRATE)) { - runstate_set(RUN_STATE_POSTMIGRATE); + runstate_set(s->vm_old_state); } } break; @@ -2788,6 +2781,13 @@ static void migration_iteration_finish(MigrationState *s) static void bg_migration_iteration_finish(MigrationState *s) { + /* + * Stop tracking RAM writes - un-protect memory, un-register UFFD + * memory ranges, flush kernel wait queues and wake up threads + * waiting for write fault to be resolved. + */ + ram_write_tracking_stop(); + qemu_mutex_lock_iothread(); switch (s->state) { case MIGRATION_STATUS_COMPLETED: @@ -3086,11 +3086,9 @@ static void *bg_migration_thread(void *opaque) * transition in vm_stop_force_state() we need to wakeup it up. */ qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, NULL); - s->vm_was_running = runstate_is_running(); + s->vm_old_state = runstate_get(); - if (global_state_store()) { - goto fail; - } + global_state_store(); /* Forcibly stop VM before saving state of vCPUs and devices */ if (vm_stop_force_state(RUN_STATE_PAUSED)) { goto fail; diff --git a/migration/migration.h b/migration/migration.h index 48a46123a0..30c3e97635 100644 --- a/migration/migration.h +++ b/migration/migration.h @@ -25,6 +25,7 @@ #include "net/announce.h" #include "qom/object.h" #include "postcopy-ram.h" +#include "sysemu/runstate.h" struct PostcopyBlocktimeContext; @@ -317,12 +318,14 @@ struct MigrationState { int64_t expected_downtime; bool capabilities[MIGRATION_CAPABILITY__MAX]; int64_t setup_time; + /* - * Whether guest was running when we enter the completion stage. + * State before stopping the vm by vm_stop_force_state(). * If migration is interrupted by any reason, we need to continue - * running the guest on source. + * running the guest on source if it was running or restore its stopped + * state. */ - bool vm_was_running; + RunState vm_old_state; /* Flag set once the migration has been asked to enter postcopy */ bool start_postcopy; diff --git a/migration/savevm.c b/migration/savevm.c index 03795ce8dc..bc284087f9 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -2919,11 +2919,7 @@ bool save_snapshot(const char *name, bool overwrite, const char *vmstate, saved_vm_running = runstate_is_running(); - ret = global_state_store(); - if (ret) { - error_setg(errp, "Error saving global state"); - return false; - } + global_state_store(); vm_stop(RUN_STATE_SAVE_VM); bdrv_drain_all_begin(); diff --git a/softmmu/runstate.c b/softmmu/runstate.c index 2f2396c819..1957caf73f 100644 --- a/softmmu/runstate.c +++ b/softmmu/runstate.c @@ -121,7 +121,13 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_FINISH_MIGRATE, RUN_STATE_PAUSED }, { RUN_STATE_FINISH_MIGRATE, RUN_STATE_POSTMIGRATE }, { RUN_STATE_FINISH_MIGRATE, RUN_STATE_PRELAUNCH }, - { RUN_STATE_FINISH_MIGRATE, RUN_STATE_COLO}, + { RUN_STATE_FINISH_MIGRATE, RUN_STATE_COLO }, + { RUN_STATE_FINISH_MIGRATE, RUN_STATE_INTERNAL_ERROR }, + { RUN_STATE_FINISH_MIGRATE, RUN_STATE_IO_ERROR }, + { RUN_STATE_FINISH_MIGRATE, RUN_STATE_SHUTDOWN }, + { RUN_STATE_FINISH_MIGRATE, RUN_STATE_SUSPENDED }, + { RUN_STATE_FINISH_MIGRATE, RUN_STATE_WATCHDOG }, + { RUN_STATE_FINISH_MIGRATE, RUN_STATE_GUEST_PANICKED }, { RUN_STATE_RESTORE_VM, RUN_STATE_RUNNING }, { RUN_STATE_RESTORE_VM, RUN_STATE_PRELAUNCH }, @@ -175,18 +181,6 @@ bool runstate_check(RunState state) return current_run_state == state; } -bool runstate_store(char *str, size_t size) -{ - const char *state = RunState_str(current_run_state); - size_t len = strlen(state) + 1; - - if (len > size) { - return false; - } - memcpy(str, state, len); - return true; -} - static void runstate_init(void) { const RunStateTransition *p; @@ -221,6 +215,11 @@ void runstate_set(RunState new_state) current_run_state = new_state; } +RunState runstate_get(void) +{ + return current_run_state; +} + bool runstate_is_running(void) { return runstate_check(RUN_STATE_RUNNING); |