diff options
author | Fabiano Rosas <farosas@suse.de> | 2023-06-07 13:13:05 -0300 |
---|---|---|
committer | Juan Quintela <quintela@redhat.com> | 2023-07-26 10:55:56 +0200 |
commit | 01ec0f3a9211cf4af88706188865b15ad53f7d76 (patch) | |
tree | acac079fdf4eaef2624ab255868f742e207f6f8f /migration | |
parent | 788fa680419854db44205ec6e74602b5f91ee98d (diff) |
migration/multifd: Protect accesses to migration_threads
This doubly linked list is common for all the multifd and migration
threads so we need to avoid concurrent access.
Add a mutex to protect the data from concurrent access. This fixes a
crash when removing two MigrationThread objects from the list at the
same time during cleanup of multifd threads.
Fixes: 671326201d ("migration: Introduce interface query-migrationthreads")
Signed-off-by: Fabiano Rosas <farosas@suse.de>
Reviewed-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Message-Id: <20230607161306.31425-3-farosas@suse.de>
Signed-off-by: Juan Quintela <quintela@redhat.com>
Diffstat (limited to 'migration')
-rw-r--r-- | migration/threadinfo.c | 15 | ||||
-rw-r--r-- | migration/threadinfo.h | 2 |
2 files changed, 14 insertions, 3 deletions
diff --git a/migration/threadinfo.c b/migration/threadinfo.c index 3dd9b14ae6..262990dd75 100644 --- a/migration/threadinfo.c +++ b/migration/threadinfo.c @@ -10,23 +10,35 @@ * See the COPYING file in the top-level directory. */ +#include "qemu/osdep.h" +#include "qemu/queue.h" +#include "qemu/lockable.h" #include "threadinfo.h" +QemuMutex migration_threads_lock; static QLIST_HEAD(, MigrationThread) migration_threads; +static void __attribute__((constructor)) migration_threads_init(void) +{ + qemu_mutex_init(&migration_threads_lock); +} + MigrationThread *migration_threads_add(const char *name, int thread_id) { MigrationThread *thread = g_new0(MigrationThread, 1); thread->name = name; thread->thread_id = thread_id; - QLIST_INSERT_HEAD(&migration_threads, thread, node); + WITH_QEMU_LOCK_GUARD(&migration_threads_lock) { + QLIST_INSERT_HEAD(&migration_threads, thread, node); + } return thread; } void migration_threads_remove(MigrationThread *thread) { + QEMU_LOCK_GUARD(&migration_threads_lock); if (thread) { QLIST_REMOVE(thread, node); g_free(thread); @@ -39,6 +51,7 @@ MigrationThreadInfoList *qmp_query_migrationthreads(Error **errp) MigrationThreadInfoList **tail = &head; MigrationThread *thread = NULL; + QEMU_LOCK_GUARD(&migration_threads_lock); QLIST_FOREACH(thread, &migration_threads, node) { MigrationThreadInfo *info = g_new0(MigrationThreadInfo, 1); info->name = g_strdup(thread->name); diff --git a/migration/threadinfo.h b/migration/threadinfo.h index 8aa6999d58..2f356ff312 100644 --- a/migration/threadinfo.h +++ b/migration/threadinfo.h @@ -10,8 +10,6 @@ * See the COPYING file in the top-level directory. */ -#include "qemu/queue.h" -#include "qemu/osdep.h" #include "qapi/error.h" #include "qapi/qapi-commands-migration.h" |