1661
migration_reset_vfio_bytes_transferred();
1662
1663
s->postcopy_package_loaded = false;
1664
- qemu_event_reset(&s->postcopy_package_loaded_event);
1664
1665
return 0;
1666
}
2316
if (tmp32 == QEMU_VM_PING_PACKAGED_LOADED) {
2317
trace_source_return_path_thread_postcopy_package_loaded();
2318
ms->postcopy_package_loaded = true;
2320
- qemu_event_set(&ms->postcopy_package_loaded_event);
2319
+ migration_rp_kick(ms);
2320
}
2321
break;
2322
2387
trace_source_return_path_thread_bad_end();
2388
}
2389
2391
- if (ms->state == MIGRATION_STATUS_POSTCOPY_RECOVER) {
2390
+ if (ms->state == MIGRATION_STATUS_POSTCOPY_RECOVER ||
2391
+ ms->state == MIGRATION_STATUS_POSTCOPY_DEVICE) {
2392
/*
2393
- * this will be extremely unlikely: that we got yet another network
2394
- * issue during recovering of the 1st network failure.. during this
2395
- * period the main migration thread can be waiting on rp_sem for
2396
- * this thread to sync with the other side.
2393
+ * The migration thread can get stuck waiting for rp_sem if the
2394
+ * return path fails to sync with the destination. This handles
2395
+ * two specific cases:
2396
*
2398
- * When this happens, explicitly kick the migration thread out of
2399
- * RECOVER stage and back to PAUSED, so the admin can try
2400
- * everything again.
2397
+ * POSTCOPY_RECOVER: A failure occurs during a recovery attempt.
2398
+ * We kick the migration thread back to PAUSED so the admin can
2399
+ * retry.
2400
+ *
2401
+ * POSTCOPY_DEVICE: The MIG_RP_MSG_PONG is lost due to a
2402
+ * network failure or destination crash. We kick the migration
2403
+ * thread out of its wait so it can fail the migration and safely
2404
+ * resume the VM on the source.
2405
*/
2406
migration_rp_kick(ms);
2407
}
3230
if (s->state == MIGRATION_STATUS_POSTCOPY_DEVICE &&
3231
(s->postcopy_package_loaded || complete_ready)) {
3232
/*
3229
- * If package has been loaded, the event is set and we will
3230
- * immediatelly transition to POSTCOPY_ACTIVE. If we are ready for
3231
- * completion, we need to wait for destination to load the postcopy
3232
- * package before actually completing.
3233
+ * We will immediately transition to POSTCOPY_ACTIVE.
3234
+ * If we are ready for completion, we need to wait for
3235
+ * destination to load the postcopy package before actually
3236
+ * completing.
3237
*/
3234
- qemu_event_wait(&s->postcopy_package_loaded_event);
3238
+ while (!s->postcopy_package_loaded) {
3239
+ if (migration_rp_wait(s)) {
3240
+ /*
3241
+ * Error happened. Migration thread was stuck waiting in
3242
+ * POSTCOPY_DEVICE for rp_sem which was never set.
3243
+ */
3244
+ migrate_set_state(&s->state,
3245
+ MIGRATION_STATUS_POSTCOPY_DEVICE,
3246
+ MIGRATION_STATUS_FAILING);
3247
+ return MIG_ITERATE_BREAK;
3248
+ }
3249
+ }
3250
+ /* Acknowledgement received from the destination */
3251
migrate_set_state(&s->state, MIGRATION_STATUS_POSTCOPY_DEVICE,
3252
MIGRATION_STATUS_POSTCOPY_ACTIVE);
3253
}
3879
qemu_sem_destroy(&ms->rp_state.rp_pong_acks);
3880
qemu_sem_destroy(&ms->postcopy_qemufile_src_sem);
3881
error_free(ms->error);
3866
- qemu_event_destroy(&ms->postcopy_package_loaded_event);
3882
}
3883
3884
static void migration_instance_init(Object *obj)
3900
qemu_sem_init(&ms->wait_unplug_sem, 0);
3901
qemu_sem_init(&ms->postcopy_qemufile_src_sem, 0);
3902
qemu_mutex_init(&ms->qemu_file_lock);
3888
- qemu_event_init(&ms->postcopy_package_loaded_event, 0);
3903
}
3904
3905
/*