From: Juan Quintela <quintela@redhat.com>
To: Wei Wang <wei.w.wang@intel.com>
Cc: peterx@redhat.com, isaku.yamahata@gmail.com, qemu-devel@nongnu.org
Subject: Re: [PATCH v2] migration: refactor migration_completion
Date: Wed, 11 Oct 2023 14:41:17 +0200 [thread overview]
Message-ID: <87v8bdbac2.fsf@secure.mitica> (raw)
In-Reply-To: <20230804093053.5037-1-wei.w.wang@intel.com> (Wei Wang's message of "Fri, 4 Aug 2023 17:30:53 +0800")
Wei Wang <wei.w.wang@intel.com> wrote:
> Current migration_completion function is a bit long. Refactor the long
> implementation into different subfunctions:
> - migration_completion_precopy: completion code related to precopy
> - migration_completion_postcopy: completion code related to postcopy
> - close_return_path_on_source: rp thread related cleanup on migration
> completion. It is named to match with open_return_path_on_source.
>
> This improves readability and is easier for future updates (e.g. add new
> subfunctions when completion code related to new features are needed). No
> functional changes intended.
>
> Signed-off-by: Wei Wang <wei.w.wang@intel.com>
There was some conflict with:
commit d50f5dc075cbb891bfe4a9378600a4871264468a
Author: Fabiano Rosas <farosas@suse.de>
Date: Mon Sep 18 14:28:20 2023 -0300
migration: Consolidate return path closing code
(basically the traces and the rp_thread_created check were already on
the tree).
BTW, the diff is uglier than it needs to be.
You can add to your global .gitconfig:
[diff]
algorithm = patience
renames = true
commit e2db83d6e73df7619de75093d1477a7f3c638847
Author: Wei Wang <wei.w.wang@intel.com>
Date: Fri Aug 4 17:30:53 2023 +0800
migration: refactor migration_completion
Current migration_completion function is a bit long. Refactor the long
implementation into different subfunctions:
- migration_completion_precopy: completion code related to precopy
- migration_completion_postcopy: completion code related to postcopy
- close_return_path_on_source: rp thread related cleanup on migration
completion. It is named to match with open_return_path_on_source.
This improves readability and is easier for future updates (e.g. add new
subfunctions when completion code related to new features are needed). No
functional changes intended.
Signed-off-by: Wei Wang <wei.w.wang@intel.com>
diff --git a/migration/migration.c b/migration/migration.c
index 1c6c81ad49..99a06832f5 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -99,7 +99,7 @@ static int migration_maybe_pause(MigrationState *s,
int *current_active_state,
int new_state);
static void migrate_fd_cancel(MigrationState *s);
-static int await_return_path_close_on_source(MigrationState *s);
+static int close_return_path_on_source(MigrationState *s);
static bool migration_needs_multiple_sockets(void)
{
@@ -1191,7 +1191,7 @@ static void migrate_fd_cleanup(MigrationState *s)
* We already cleaned up to_dst_file, so errors from the return
* path might be due to that, ignore them.
*/
- await_return_path_close_on_source(s);
+ close_return_path_on_source(s);
assert(!migration_is_active(s));
@@ -2049,8 +2049,7 @@ static int open_return_path_on_source(MigrationState *ms)
return 0;
}
-/* Returns 0 if the RP was ok, otherwise there was an error on the RP */
-static int await_return_path_close_on_source(MigrationState *ms)
+static int close_return_path_on_source(MigrationState *ms)
{
int ret;
@@ -2317,6 +2316,87 @@ static int migration_maybe_pause(MigrationState *s,
return s->state == new_state ? 0 : -EINVAL;
}
+static int migration_completion_precopy(MigrationState *s,
+ int *current_active_state)
+{
+ int ret;
+
+ 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_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) {
+ goto out_unlock;
+ }
+
+ ret = migration_maybe_pause(s, current_active_state,
+ MIGRATION_STATUS_DEVICE);
+ if (ret < 0) {
+ goto out_unlock;
+ }
+
+ /*
+ * 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);
+out_unlock:
+ qemu_mutex_unlock_iothread();
+ return ret;
+}
+
+static void migration_completion_postcopy(MigrationState *s)
+{
+ trace_migration_completion_postcopy_end();
+
+ qemu_mutex_lock_iothread();
+ qemu_savevm_state_complete_postcopy(s->to_dst_file);
+ qemu_mutex_unlock_iothread();
+
+ /*
+ * Shutdown the postcopy fast path thread. This is only needed when dest
+ * QEMU binary is old (7.1/7.2). QEMU 8.0+ doesn't need this.
+ */
+ if (migrate_postcopy_preempt() && s->preempt_pre_7_2) {
+ postcopy_preempt_shutdown_file(s);
+ }
+
+ trace_migration_completion_postcopy_end_after_complete();
+}
+
+static void migration_completion_failed(MigrationState *s,
+ int current_active_state)
+{
+ if (s->block_inactive && (s->state == MIGRATION_STATUS_ACTIVE ||
+ s->state == MIGRATION_STATUS_DEVICE)) {
+ /*
+ * If not doing postcopy, vm_start() will be called: let's
+ * regain control on images.
+ */
+ Error *local_err = NULL;
+
+ qemu_mutex_lock_iothread();
+ bdrv_activate_all(&local_err);
+ if (local_err) {
+ error_report_err(local_err);
+ } else {
+ s->block_inactive = false;
+ }
+ qemu_mutex_unlock_iothread();
+ }
+
+ migrate_set_state(&s->state, current_active_state,
+ MIGRATION_STATUS_FAILED);
+}
+
/**
* migration_completion: Used by migration_thread when there's not much left.
* The caller 'breaks' the loop when this returns.
@@ -2325,62 +2405,22 @@ static int migration_maybe_pause(MigrationState *s,
*/
static void migration_completion(MigrationState *s)
{
- int ret;
+ int ret = 0;
int current_active_state = s->state;
if (s->state == MIGRATION_STATUS_ACTIVE) {
- 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_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) {
- goto fail;
- }
+ ret = migration_completion_precopy(s, ¤t_active_state);
} else if (s->state == MIGRATION_STATUS_POSTCOPY_ACTIVE) {
- trace_migration_completion_postcopy_end();
-
- qemu_mutex_lock_iothread();
- qemu_savevm_state_complete_postcopy(s->to_dst_file);
- qemu_mutex_unlock_iothread();
-
- /*
- * Shutdown the postcopy fast path thread. This is only needed
- * when dest QEMU binary is old (7.1/7.2). QEMU 8.0+ doesn't need
- * this.
- */
- if (migrate_postcopy_preempt() && s->preempt_pre_7_2) {
- postcopy_preempt_shutdown_file(s);
- }
-
- trace_migration_completion_postcopy_end_after_complete();
+ migration_completion_postcopy(s);
} else {
+ ret = -1;
+ }
+
+ if (ret < 0) {
goto fail;
}
- if (await_return_path_close_on_source(s)) {
+ if (close_return_path_on_source(s) < 0) {
goto fail;
}
@@ -2401,26 +2441,7 @@ static void migration_completion(MigrationState *s)
return;
fail:
- if (s->block_inactive && (s->state == MIGRATION_STATUS_ACTIVE ||
- s->state == MIGRATION_STATUS_DEVICE)) {
- /*
- * If not doing postcopy, vm_start() will be called: let's
- * regain control on images.
- */
- Error *local_err = NULL;
-
- qemu_mutex_lock_iothread();
- bdrv_activate_all(&local_err);
- if (local_err) {
- error_report_err(local_err);
- } else {
- s->block_inactive = false;
- }
- qemu_mutex_unlock_iothread();
- }
-
- migrate_set_state(&s->state, current_active_state,
- MIGRATION_STATUS_FAILED);
+ migration_completion_failed(s, current_active_state);
}
/**
@@ -2563,7 +2584,7 @@ static MigThrError postcopy_pause(MigrationState *s)
* path and just wait for the thread to finish. It will be
* re-created when we resume.
*/
- await_return_path_close_on_source(s);
+ close_return_path_on_source(s);
migrate_set_state(&s->state, s->state,
MIGRATION_STATUS_POSTCOPY_PAUSED);
next prev parent reply other threads:[~2023-10-11 12:43 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-04 9:30 [PATCH v2] migration: refactor migration_completion Wei Wang
2023-08-04 13:37 ` Peter Xu
2023-10-11 9:03 ` Wang, Wei W
2023-08-14 22:14 ` Isaku Yamahata
2023-10-11 11:22 ` Juan Quintela
2023-10-11 12:41 ` Juan Quintela [this message]
2023-10-11 14:45 ` Wang, Wei W
2023-10-11 20:31 ` Juan Quintela
2023-10-12 14:36 ` Wang, Wei W
2023-10-12 14:43 ` Wang, Wei W
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87v8bdbac2.fsf@secure.mitica \
--to=quintela@redhat.com \
--cc=isaku.yamahata@gmail.com \
--cc=peterx@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=wei.w.wang@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.