@@ -551,4 +551,7 @@ int migration_rp_wait(MigrationState *s);
*/
void migration_rp_kick(MigrationState *s);
+void migration_threads_add(const char *name);
+void migration_threads_remove(void);
+
#endif
@@ -20,6 +20,3 @@ struct MigrationThread {
int thread_id; /* ID of the underlying host thread */
QLIST_ENTRY(MigrationThread) node;
};
-
-void migration_threads_add(const char *name);
-void migration_threads_remove(void);
@@ -823,6 +823,7 @@ static void *colo_process_incoming_thread(void *opaque)
QIOChannelBuffer *bioc = NULL; /* Cache incoming device state */
Error *local_err = NULL;
+ migration_threads_add(MIGRATION_THREAD_DST_COLO);
rcu_register_thread();
qemu_sem_init(&mis->colo_incoming_sem, 0);
@@ -831,7 +832,7 @@ static void *colo_process_incoming_thread(void *opaque)
if (get_colo_mode() != COLO_MODE_SECONDARY) {
error_report("COLO mode must be COLO_MODE_SECONDARY");
- return NULL;
+ goto out_last;
}
/* Make sure all file formats throw away their mutable metadata */
@@ -840,7 +841,7 @@ static void *colo_process_incoming_thread(void *opaque)
bql_unlock();
if (local_err) {
error_report_err(local_err);
- return NULL;
+ goto out_last;
}
failover_init_state();
@@ -923,7 +924,9 @@ out:
qemu_sem_wait(&mis->colo_incoming_sem);
qemu_sem_destroy(&mis->colo_incoming_sem);
+out_last:
rcu_unregister_thread();
+ migration_threads_remove();
return NULL;
}
@@ -729,13 +729,15 @@ void *get_dirtyrate_thread(void *arg)
{
struct DirtyRateConfig config = *(struct DirtyRateConfig *)arg;
int ret;
+
+ migration_threads_add(MIGRATION_THREAD_DIRTY_RATE);
rcu_register_thread();
ret = dirtyrate_set_state(&CalculatingState, DIRTY_RATE_STATUS_UNSTARTED,
DIRTY_RATE_STATUS_MEASURING);
if (ret == -1) {
error_report("change dirtyrate state failed.");
- return NULL;
+ goto out;
}
calculate_dirtyrate(config);
@@ -746,7 +748,10 @@ void *get_dirtyrate_thread(void *arg)
error_report("change dirtyrate state failed.");
}
+out:
rcu_unregister_thread();
+ migration_threads_remove();
+
return NULL;
}
@@ -2321,6 +2321,7 @@ static void *source_return_path_thread(void *opaque)
int res;
trace_source_return_path_thread_entry();
+ migration_threads_add(MIGRATION_THREAD_SRC_RETURN);
rcu_register_thread();
while (migration_is_setup_or_active()) {
@@ -2463,8 +2464,9 @@ out:
migration_rp_kick(ms);
}
- trace_source_return_path_thread_end();
rcu_unregister_thread();
+ migration_threads_remove();
+ trace_source_return_path_thread_end();
return NULL;
}
@@ -3602,6 +3604,8 @@ static void *bg_migration_thread(void *opaque)
Error *local_err = NULL;
int ret;
+ migration_threads_add(MIGRATION_THREAD_SNAPSHOT);
+
rcu_register_thread();
object_ref(OBJECT(s));
@@ -3726,6 +3730,7 @@ fail_setup:
qemu_fclose(fb);
object_unref(OBJECT(s));
rcu_unregister_thread();
+ migration_threads_remove();
return NULL;
}
@@ -685,6 +685,8 @@ static void *multifd_tls_handshake_thread(void *opaque)
{
MultiFDTLSThreadArgs *args = opaque;
+ migration_threads_add(MIGRATION_THREAD_SRC_TLS);
+
qio_channel_tls_handshake(args->tioc,
multifd_new_send_channel_async,
args->p,
@@ -692,6 +694,8 @@ static void *multifd_tls_handshake_thread(void *opaque)
NULL);
g_free(args);
+ migration_threads_remove();
+
return NULL;
}
@@ -1122,6 +1126,7 @@ static void *multifd_recv_thread(void *opaque)
int ret;
trace_multifd_recv_thread_start(p->id);
+ migration_threads_add(MIGRATION_THREAD_DST_MULTIFD);
rcu_register_thread();
while (true) {
@@ -1209,6 +1214,7 @@ static void *multifd_recv_thread(void *opaque)
}
rcu_unregister_thread();
+ migration_threads_remove();
trace_multifd_recv_thread_end(p->id, p->packets_recved);
return NULL;
@@ -962,6 +962,7 @@ static void *postcopy_ram_fault_thread(void *opaque)
RAMBlock *rb = NULL;
trace_postcopy_ram_fault_thread_entry();
+ migration_threads_add(MIGRATION_THREAD_DST_FAULT);
rcu_register_thread();
mis->last_rb = NULL; /* last RAMBlock we sent part of */
qemu_sem_post(&mis->thread_sync_sem);
@@ -1142,9 +1143,12 @@ retry:
}
}
}
+
+ g_free(pfd);
rcu_unregister_thread();
+ migration_threads_remove();
trace_postcopy_ram_fault_thread_exit();
- g_free(pfd);
+
return NULL;
}
@@ -1713,7 +1717,7 @@ void *postcopy_preempt_thread(void *opaque)
int ret;
trace_postcopy_preempt_thread_entry();
-
+ migration_threads_add(MIGRATION_THREAD_DST_PREEMPT);
rcu_register_thread();
qemu_sem_post(&mis->thread_sync_sem);
@@ -1740,7 +1744,7 @@ void *postcopy_preempt_thread(void *opaque)
qemu_mutex_unlock(&mis->postcopy_prio_thread_mutex);
rcu_unregister_thread();
-
+ migration_threads_remove();
trace_postcopy_preempt_thread_exit();
return NULL;
@@ -2002,14 +2002,15 @@ static void *postcopy_ram_listen_thread(void *opaque)
int load_res;
MigrationState *migr = migrate_get_current();
- object_ref(OBJECT(migr));
+ trace_postcopy_ram_listen_thread_start();
+ migration_threads_add(MIGRATION_THREAD_DST_LISTEN);
+ rcu_register_thread();
+ object_ref(OBJECT(migr));
migrate_set_state(&mis->state, MIGRATION_STATUS_ACTIVE,
MIGRATION_STATUS_POSTCOPY_ACTIVE);
qemu_sem_post(&mis->thread_sync_sem);
- trace_postcopy_ram_listen_thread_start();
- rcu_register_thread();
/*
* Because we're a thread and not a coroutine we can't yield
* in qemu_file, and thus we must be blocking now.
@@ -2078,11 +2079,12 @@ static void *postcopy_ram_listen_thread(void *opaque)
migration_incoming_state_destroy();
qemu_loadvm_state_cleanup();
- rcu_unregister_thread();
mis->have_listen_thread = false;
postcopy_state_set(POSTCOPY_INCOMING_END);
object_unref(OBJECT(migr));
+ rcu_unregister_thread();
+ migration_threads_remove();
return NULL;
}
@@ -14,6 +14,7 @@
#include "qemu/queue.h"
#include "qemu/lockable.h"
#include "threadinfo.h"
+#include "migration.h"
QemuMutex migration_threads_lock;
static QLIST_HEAD(, MigrationThread) migration_threads;
The QMP interface query-migrationthreads lacks a lot of migration threads but only reports multifd sender threads. That's incomplete. Since I'm at this, make all threads available to the QMP responses. NOTE: there're a few changes that should fix some bugs on e.g. not unregister rcu threads on failure paths, but I didn't make them separate because they do not exist in live migration main logics but only either COLO or dirty rate thread on rare failures. I'd not bother, but if anyone things we should split it out feel free to shoot. Signed-off-by: Peter Xu <peterx@redhat.com> --- migration/migration.h | 3 +++ migration/threadinfo.h | 3 --- migration/colo.c | 7 +++++-- migration/dirtyrate.c | 7 ++++++- migration/migration.c | 7 ++++++- migration/multifd.c | 6 ++++++ migration/postcopy-ram.c | 10 +++++++--- migration/savevm.c | 10 ++++++---- migration/threadinfo.c | 1 + 9 files changed, 40 insertions(+), 14 deletions(-)