diff options
Diffstat (limited to 'migration/migration.c')
-rw-r--r-- | migration/migration.c | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/migration/migration.c b/migration/migration.c index 4844ad438b..d0a0f68f11 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -1495,10 +1495,8 @@ static void block_cleanup_parameters(MigrationState *s) } } -static void migrate_fd_cleanup(void *opaque) +static void migrate_fd_cleanup(MigrationState *s) { - MigrationState *s = opaque; - qemu_bh_delete(s->cleanup_bh); s->cleanup_bh = NULL; @@ -1543,6 +1541,23 @@ static void migrate_fd_cleanup(void *opaque) block_cleanup_parameters(s); } +static void migrate_fd_cleanup_schedule(MigrationState *s) +{ + /* + * Ref the state for bh, because it may be called when + * there're already no other refs + */ + object_ref(OBJECT(s)); + qemu_bh_schedule(s->cleanup_bh); +} + +static void migrate_fd_cleanup_bh(void *opaque) +{ + MigrationState *s = opaque; + migrate_fd_cleanup(s); + object_unref(OBJECT(s)); +} + void migrate_set_error(MigrationState *s, const Error *error) { qemu_mutex_lock(&s->error_mutex); @@ -3143,7 +3158,7 @@ static void migration_iteration_finish(MigrationState *s) error_report("%s: Unknown ending state %d", __func__, s->state); break; } - qemu_bh_schedule(s->cleanup_bh); + migrate_fd_cleanup_schedule(s); qemu_mutex_unlock_iothread(); } @@ -3278,7 +3293,7 @@ void migrate_fd_connect(MigrationState *s, Error *error_in) bool resume = s->state == MIGRATION_STATUS_POSTCOPY_PAUSED; s->expected_downtime = s->parameters.downtime_limit; - s->cleanup_bh = qemu_bh_new(migrate_fd_cleanup, s); + s->cleanup_bh = qemu_bh_new(migrate_fd_cleanup_bh, s); if (error_in) { migrate_fd_error(s, error_in); migrate_fd_cleanup(s); |