* Peter Xu (pet...@redhat.com) wrote: > Now at least migrate_incoming can be run in parallel. Let's provide a > migration lock to protect it. > > Signed-off-by: Peter Xu <pet...@redhat.com> > --- > migration/migration.c | 6 ++++++ > migration/migration.h | 3 +++ > 2 files changed, 9 insertions(+) > > diff --git a/migration/migration.c b/migration/migration.c > index c3fe0ed..32058f7 100644 > --- a/migration/migration.c > +++ b/migration/migration.c > @@ -145,6 +145,7 @@ MigrationIncomingState > *migration_incoming_get_current(void) > mis_current.state = MIGRATION_STATUS_NONE; > memset(&mis_current, 0, sizeof(MigrationIncomingState)); > qemu_mutex_init(&mis_current.rp_mutex); > + qemu_mutex_init(&mis_current.mgmt_mutex); > qemu_event_init(&mis_current.main_thread_load_event, false); > once = true; > } > @@ -1171,6 +1172,7 @@ void qmp_migrate_incoming(const char *uri, Error **errp) > { > Error *local_err = NULL; > static bool once = true; > + MigrationIncomingState *mis = migration_incoming_get_current();
migration_incoming_get_current isn't actually thread-safe itself unless you can guarantee the initial allocation has happened - otherwise both threads can race and do the 'once' code at the same time. Similarly, these locks - they don't protect our 'once' - so a second thread could come in here and both get past the !once check. Dave > > if (!deferred_incoming) { > error_setg(errp, "For use with '-incoming defer'"); > @@ -1180,8 +1182,12 @@ void qmp_migrate_incoming(const char *uri, Error > **errp) > error_setg(errp, "The incoming migration has already been started"); > } > > + qemu_mutex_lock(&mis->mgmt_mutex); > + > qemu_start_incoming_migration(uri, &local_err); > > + qemu_mutex_unlock(&mis->mgmt_mutex); > + > if (local_err) { > error_propagate(errp, local_err); > return; > diff --git a/migration/migration.h b/migration/migration.h > index 148c9fa..95f077b 100644 > --- a/migration/migration.h > +++ b/migration/migration.h > @@ -58,6 +58,9 @@ struct MigrationIncomingState { > /* The coroutine we should enter (back) after failover */ > Coroutine *migration_incoming_co; > QemuSemaphore colo_incoming_sem; > + > + /* Migration incoming management lock */ > + QemuMutex mgmt_mutex; > }; > > MigrationIncomingState *migration_incoming_get_current(void); > -- > 2.7.4 > -- Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK