[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 20/34] migration/multifd: Cleanup multifd_save_cleanup()
From: |
peterx |
Subject: |
[PULL 20/34] migration/multifd: Cleanup multifd_save_cleanup() |
Date: |
Thu, 8 Feb 2024 11:05:14 +0800 |
From: Peter Xu <peterx@redhat.com>
Shrink the function by moving relevant works into helpers: move the thread
join()s into multifd_send_terminate_threads(), then create two more helpers
to cover channel/state cleanups.
Add a TODO entry for the thread terminate process because p->running is
still buggy. We need to fix it at some point but not yet covered.
Suggested-by: Fabiano Rosas <farosas@suse.de>
Reviewed-by: Fabiano Rosas <farosas@suse.de>
Link: 20240202102857.110210-20-peterx@redhat.com">https://lore.kernel.org/r/20240202102857.110210-20-peterx@redhat.com
Signed-off-by: Peter Xu <peterx@redhat.com>
---
migration/multifd.c | 91 +++++++++++++++++++++++++++++----------------
1 file changed, 59 insertions(+), 32 deletions(-)
diff --git a/migration/multifd.c b/migration/multifd.c
index 4ab8e6eff2..4cb0d2cc17 100644
--- a/migration/multifd.c
+++ b/migration/multifd.c
@@ -593,6 +593,11 @@ static void multifd_send_terminate_threads(void)
* always set it.
*/
qatomic_set(&multifd_send_state->exiting, 1);
+
+ /*
+ * Firstly, kick all threads out; no matter whether they are just idle,
+ * or blocked in an IO system call.
+ */
for (i = 0; i < migrate_multifd_channels(); i++) {
MultiFDSendParams *p = &multifd_send_state->params[i];
@@ -601,6 +606,21 @@ static void multifd_send_terminate_threads(void)
qio_channel_shutdown(p->c, QIO_CHANNEL_SHUTDOWN_BOTH, NULL);
}
}
+
+ /*
+ * Finally recycle all the threads.
+ *
+ * TODO: p->running is still buggy, e.g. we can reach here without the
+ * corresponding multifd_new_send_channel_async() get invoked yet,
+ * then a new thread can even be created after this function returns.
+ */
+ for (i = 0; i < migrate_multifd_channels(); i++) {
+ MultiFDSendParams *p = &multifd_send_state->params[i];
+
+ if (p->running) {
+ qemu_thread_join(&p->thread);
+ }
+ }
}
static int multifd_send_channel_destroy(QIOChannel *send)
@@ -608,6 +628,41 @@ static int multifd_send_channel_destroy(QIOChannel *send)
return socket_send_channel_destroy(send);
}
+static bool multifd_send_cleanup_channel(MultiFDSendParams *p, Error **errp)
+{
+ if (p->registered_yank) {
+ migration_ioc_unregister_yank(p->c);
+ }
+ multifd_send_channel_destroy(p->c);
+ p->c = NULL;
+ qemu_mutex_destroy(&p->mutex);
+ qemu_sem_destroy(&p->sem);
+ qemu_sem_destroy(&p->sem_sync);
+ g_free(p->name);
+ p->name = NULL;
+ multifd_pages_clear(p->pages);
+ p->pages = NULL;
+ p->packet_len = 0;
+ g_free(p->packet);
+ p->packet = NULL;
+ g_free(p->iov);
+ p->iov = NULL;
+ multifd_send_state->ops->send_cleanup(p, errp);
+
+ return *errp == NULL;
+}
+
+static void multifd_send_cleanup_state(void)
+{
+ qemu_sem_destroy(&multifd_send_state->channels_ready);
+ g_free(multifd_send_state->params);
+ multifd_send_state->params = NULL;
+ multifd_pages_clear(multifd_send_state->pages);
+ multifd_send_state->pages = NULL;
+ g_free(multifd_send_state);
+ multifd_send_state = NULL;
+}
+
void multifd_save_cleanup(void)
{
int i;
@@ -615,48 +670,20 @@ void multifd_save_cleanup(void)
if (!migrate_multifd()) {
return;
}
+
multifd_send_terminate_threads();
- for (i = 0; i < migrate_multifd_channels(); i++) {
- MultiFDSendParams *p = &multifd_send_state->params[i];
- if (p->running) {
- qemu_thread_join(&p->thread);
- }
- }
for (i = 0; i < migrate_multifd_channels(); i++) {
MultiFDSendParams *p = &multifd_send_state->params[i];
Error *local_err = NULL;
- if (p->registered_yank) {
- migration_ioc_unregister_yank(p->c);
- }
- multifd_send_channel_destroy(p->c);
- p->c = NULL;
- qemu_mutex_destroy(&p->mutex);
- qemu_sem_destroy(&p->sem);
- qemu_sem_destroy(&p->sem_sync);
- g_free(p->name);
- p->name = NULL;
- multifd_pages_clear(p->pages);
- p->pages = NULL;
- p->packet_len = 0;
- g_free(p->packet);
- p->packet = NULL;
- g_free(p->iov);
- p->iov = NULL;
- multifd_send_state->ops->send_cleanup(p, &local_err);
- if (local_err) {
+ if (!multifd_send_cleanup_channel(p, &local_err)) {
migrate_set_error(migrate_get_current(), local_err);
error_free(local_err);
}
}
- qemu_sem_destroy(&multifd_send_state->channels_ready);
- g_free(multifd_send_state->params);
- multifd_send_state->params = NULL;
- multifd_pages_clear(multifd_send_state->pages);
- multifd_send_state->pages = NULL;
- g_free(multifd_send_state);
- multifd_send_state = NULL;
+
+ multifd_send_cleanup_state();
}
static int multifd_zero_copy_flush(QIOChannel *c)
--
2.43.0
- [PULL 02/34] migration/multifd: Drop stale comment for multifd zero copy, (continued)
- [PULL 02/34] migration/multifd: Drop stale comment for multifd zero copy, peterx, 2024/02/07
- [PULL 03/34] migration/multifd: multifd_send_kick_main(), peterx, 2024/02/07
- [PULL 05/34] migration/multifd: Postpone reset of MultiFDPages_t, peterx, 2024/02/07
- [PULL 06/34] migration/multifd: Drop MultiFDSendParams.normal[] array, peterx, 2024/02/07
- [PULL 07/34] migration/multifd: Separate SYNC request with normal jobs, peterx, 2024/02/07
- [PULL 04/34] migration/multifd: Drop MultiFDSendParams.quit, cleanup error paths, peterx, 2024/02/07
- [PULL 08/34] migration/multifd: Simplify locking in sender thread, peterx, 2024/02/07
- [PULL 09/34] migration/multifd: Drop pages->num check in sender thread, peterx, 2024/02/07
- [PULL 13/34] migration/multifd: multifd_send_prepare_header(), peterx, 2024/02/07
- [PULL 10/34] migration/multifd: Rename p->num_packets and clean it up, peterx, 2024/02/07
- [PULL 20/34] migration/multifd: Cleanup multifd_save_cleanup(),
peterx <=
- [PULL 21/34] migration/multifd: Cleanup multifd_load_cleanup(), peterx, 2024/02/07
- [PULL 11/34] migration/multifd: Move total_normal_pages accounting, peterx, 2024/02/07
- [PULL 12/34] migration/multifd: Move trace_multifd_send|recv(), peterx, 2024/02/07
- [PULL 14/34] migration/multifd: Move header prepare/fill into send_prepare(), peterx, 2024/02/07
- [PULL 15/34] migration/multifd: Forbid spurious wakeups, peterx, 2024/02/07
- [PULL 17/34] migration/multifd: Change retval of multifd_queue_page(), peterx, 2024/02/07
- [PULL 19/34] migration/multifd: Rewrite multifd_queue_page(), peterx, 2024/02/07
- [PULL 22/34] migration/multifd: Stick with send/recv on function names, peterx, 2024/02/07
- [PULL 25/34] migration: Fix logic of channels and transport compatibility check, peterx, 2024/02/07
- [PULL 24/34] migration/multifd: Optimize sender side to be lockless, peterx, 2024/02/07