2
0

migration-multifd.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684
  1. /*
  2. * Multifd VFIO migration
  3. *
  4. * Copyright (C) 2024,2025 Oracle and/or its affiliates.
  5. *
  6. * This work is licensed under the terms of the GNU GPL, version 2 or later.
  7. * See the COPYING file in the top-level directory.
  8. *
  9. * SPDX-License-Identifier: GPL-2.0-or-later
  10. */
  11. #include "qemu/osdep.h"
  12. #include "hw/vfio/vfio-common.h"
  13. #include "migration/misc.h"
  14. #include "qapi/error.h"
  15. #include "qemu/bswap.h"
  16. #include "qemu/error-report.h"
  17. #include "qemu/lockable.h"
  18. #include "qemu/main-loop.h"
  19. #include "qemu/thread.h"
  20. #include "io/channel-buffer.h"
  21. #include "migration/qemu-file.h"
  22. #include "migration-multifd.h"
  23. #include "trace.h"
  24. #define VFIO_DEVICE_STATE_CONFIG_STATE (1)
  25. #define VFIO_DEVICE_STATE_PACKET_VER_CURRENT (0)
  26. typedef struct VFIODeviceStatePacket {
  27. uint32_t version;
  28. uint32_t idx;
  29. uint32_t flags;
  30. uint8_t data[0];
  31. } QEMU_PACKED VFIODeviceStatePacket;
  32. /* type safety */
  33. typedef struct VFIOStateBuffers {
  34. GArray *array;
  35. } VFIOStateBuffers;
  36. typedef struct VFIOStateBuffer {
  37. bool is_present;
  38. char *data;
  39. size_t len;
  40. } VFIOStateBuffer;
  41. typedef struct VFIOMultifd {
  42. bool load_bufs_thread_running;
  43. bool load_bufs_thread_want_exit;
  44. VFIOStateBuffers load_bufs;
  45. QemuCond load_bufs_buffer_ready_cond;
  46. QemuCond load_bufs_thread_finished_cond;
  47. QemuMutex load_bufs_mutex; /* Lock order: this lock -> BQL */
  48. uint32_t load_buf_idx;
  49. uint32_t load_buf_idx_last;
  50. } VFIOMultifd;
  51. static void vfio_state_buffer_clear(gpointer data)
  52. {
  53. VFIOStateBuffer *lb = data;
  54. if (!lb->is_present) {
  55. return;
  56. }
  57. g_clear_pointer(&lb->data, g_free);
  58. lb->is_present = false;
  59. }
  60. static void vfio_state_buffers_init(VFIOStateBuffers *bufs)
  61. {
  62. bufs->array = g_array_new(FALSE, TRUE, sizeof(VFIOStateBuffer));
  63. g_array_set_clear_func(bufs->array, vfio_state_buffer_clear);
  64. }
  65. static void vfio_state_buffers_destroy(VFIOStateBuffers *bufs)
  66. {
  67. g_clear_pointer(&bufs->array, g_array_unref);
  68. }
  69. static void vfio_state_buffers_assert_init(VFIOStateBuffers *bufs)
  70. {
  71. assert(bufs->array);
  72. }
  73. static unsigned int vfio_state_buffers_size_get(VFIOStateBuffers *bufs)
  74. {
  75. return bufs->array->len;
  76. }
  77. static void vfio_state_buffers_size_set(VFIOStateBuffers *bufs,
  78. unsigned int size)
  79. {
  80. g_array_set_size(bufs->array, size);
  81. }
  82. static VFIOStateBuffer *vfio_state_buffers_at(VFIOStateBuffers *bufs,
  83. unsigned int idx)
  84. {
  85. return &g_array_index(bufs->array, VFIOStateBuffer, idx);
  86. }
  87. /* called with load_bufs_mutex locked */
  88. static bool vfio_load_state_buffer_insert(VFIODevice *vbasedev,
  89. VFIODeviceStatePacket *packet,
  90. size_t packet_total_size,
  91. Error **errp)
  92. {
  93. VFIOMigration *migration = vbasedev->migration;
  94. VFIOMultifd *multifd = migration->multifd;
  95. VFIOStateBuffer *lb;
  96. vfio_state_buffers_assert_init(&multifd->load_bufs);
  97. if (packet->idx >= vfio_state_buffers_size_get(&multifd->load_bufs)) {
  98. vfio_state_buffers_size_set(&multifd->load_bufs, packet->idx + 1);
  99. }
  100. lb = vfio_state_buffers_at(&multifd->load_bufs, packet->idx);
  101. if (lb->is_present) {
  102. error_setg(errp, "%s: state buffer %" PRIu32 " already filled",
  103. vbasedev->name, packet->idx);
  104. return false;
  105. }
  106. assert(packet->idx >= multifd->load_buf_idx);
  107. lb->data = g_memdup2(&packet->data, packet_total_size - sizeof(*packet));
  108. lb->len = packet_total_size - sizeof(*packet);
  109. lb->is_present = true;
  110. return true;
  111. }
  112. bool vfio_multifd_load_state_buffer(void *opaque, char *data, size_t data_size,
  113. Error **errp)
  114. {
  115. VFIODevice *vbasedev = opaque;
  116. VFIOMigration *migration = vbasedev->migration;
  117. VFIOMultifd *multifd = migration->multifd;
  118. VFIODeviceStatePacket *packet = (VFIODeviceStatePacket *)data;
  119. if (!vfio_multifd_transfer_enabled(vbasedev)) {
  120. error_setg(errp,
  121. "%s: got device state packet but not doing multifd transfer",
  122. vbasedev->name);
  123. return false;
  124. }
  125. assert(multifd);
  126. if (data_size < sizeof(*packet)) {
  127. error_setg(errp, "%s: packet too short at %zu (min is %zu)",
  128. vbasedev->name, data_size, sizeof(*packet));
  129. return false;
  130. }
  131. packet->version = be32_to_cpu(packet->version);
  132. if (packet->version != VFIO_DEVICE_STATE_PACKET_VER_CURRENT) {
  133. error_setg(errp, "%s: packet has unknown version %" PRIu32,
  134. vbasedev->name, packet->version);
  135. return false;
  136. }
  137. packet->idx = be32_to_cpu(packet->idx);
  138. packet->flags = be32_to_cpu(packet->flags);
  139. if (packet->idx == UINT32_MAX) {
  140. error_setg(errp, "%s: packet index is invalid", vbasedev->name);
  141. return false;
  142. }
  143. trace_vfio_load_state_device_buffer_incoming(vbasedev->name, packet->idx);
  144. /*
  145. * Holding BQL here would violate the lock order and can cause
  146. * a deadlock once we attempt to lock load_bufs_mutex below.
  147. */
  148. assert(!bql_locked());
  149. WITH_QEMU_LOCK_GUARD(&multifd->load_bufs_mutex) {
  150. /* config state packet should be the last one in the stream */
  151. if (packet->flags & VFIO_DEVICE_STATE_CONFIG_STATE) {
  152. multifd->load_buf_idx_last = packet->idx;
  153. }
  154. if (!vfio_load_state_buffer_insert(vbasedev, packet, data_size,
  155. errp)) {
  156. return false;
  157. }
  158. qemu_cond_signal(&multifd->load_bufs_buffer_ready_cond);
  159. }
  160. return true;
  161. }
  162. static bool vfio_load_bufs_thread_load_config(VFIODevice *vbasedev,
  163. Error **errp)
  164. {
  165. VFIOMigration *migration = vbasedev->migration;
  166. VFIOMultifd *multifd = migration->multifd;
  167. VFIOStateBuffer *lb;
  168. g_autoptr(QIOChannelBuffer) bioc = NULL;
  169. g_autoptr(QEMUFile) f_out = NULL, f_in = NULL;
  170. uint64_t mig_header;
  171. int ret;
  172. assert(multifd->load_buf_idx == multifd->load_buf_idx_last);
  173. lb = vfio_state_buffers_at(&multifd->load_bufs, multifd->load_buf_idx);
  174. assert(lb->is_present);
  175. bioc = qio_channel_buffer_new(lb->len);
  176. qio_channel_set_name(QIO_CHANNEL(bioc), "vfio-device-config-load");
  177. f_out = qemu_file_new_output(QIO_CHANNEL(bioc));
  178. qemu_put_buffer(f_out, (uint8_t *)lb->data, lb->len);
  179. ret = qemu_fflush(f_out);
  180. if (ret) {
  181. error_setg(errp, "%s: load config state flush failed: %d",
  182. vbasedev->name, ret);
  183. return false;
  184. }
  185. qio_channel_io_seek(QIO_CHANNEL(bioc), 0, 0, NULL);
  186. f_in = qemu_file_new_input(QIO_CHANNEL(bioc));
  187. mig_header = qemu_get_be64(f_in);
  188. if (mig_header != VFIO_MIG_FLAG_DEV_CONFIG_STATE) {
  189. error_setg(errp, "%s: expected FLAG_DEV_CONFIG_STATE but got %" PRIx64,
  190. vbasedev->name, mig_header);
  191. return false;
  192. }
  193. bql_lock();
  194. ret = vfio_load_device_config_state(f_in, vbasedev);
  195. bql_unlock();
  196. if (ret < 0) {
  197. error_setg(errp, "%s: vfio_load_device_config_state() failed: %d",
  198. vbasedev->name, ret);
  199. return false;
  200. }
  201. return true;
  202. }
  203. static VFIOStateBuffer *vfio_load_state_buffer_get(VFIOMultifd *multifd)
  204. {
  205. VFIOStateBuffer *lb;
  206. unsigned int bufs_len;
  207. bufs_len = vfio_state_buffers_size_get(&multifd->load_bufs);
  208. if (multifd->load_buf_idx >= bufs_len) {
  209. assert(multifd->load_buf_idx == bufs_len);
  210. return NULL;
  211. }
  212. lb = vfio_state_buffers_at(&multifd->load_bufs,
  213. multifd->load_buf_idx);
  214. if (!lb->is_present) {
  215. return NULL;
  216. }
  217. return lb;
  218. }
  219. static bool vfio_load_state_buffer_write(VFIODevice *vbasedev,
  220. VFIOStateBuffer *lb,
  221. Error **errp)
  222. {
  223. VFIOMigration *migration = vbasedev->migration;
  224. VFIOMultifd *multifd = migration->multifd;
  225. g_autofree char *buf = NULL;
  226. char *buf_cur;
  227. size_t buf_len;
  228. if (!lb->len) {
  229. return true;
  230. }
  231. trace_vfio_load_state_device_buffer_load_start(vbasedev->name,
  232. multifd->load_buf_idx);
  233. /* lb might become re-allocated when we drop the lock */
  234. buf = g_steal_pointer(&lb->data);
  235. buf_cur = buf;
  236. buf_len = lb->len;
  237. while (buf_len > 0) {
  238. ssize_t wr_ret;
  239. int errno_save;
  240. /*
  241. * Loading data to the device takes a while,
  242. * drop the lock during this process.
  243. */
  244. qemu_mutex_unlock(&multifd->load_bufs_mutex);
  245. wr_ret = write(migration->data_fd, buf_cur, buf_len);
  246. errno_save = errno;
  247. qemu_mutex_lock(&multifd->load_bufs_mutex);
  248. if (wr_ret < 0) {
  249. error_setg(errp,
  250. "%s: writing state buffer %" PRIu32 " failed: %d",
  251. vbasedev->name, multifd->load_buf_idx, errno_save);
  252. return false;
  253. }
  254. assert(wr_ret <= buf_len);
  255. buf_len -= wr_ret;
  256. buf_cur += wr_ret;
  257. }
  258. trace_vfio_load_state_device_buffer_load_end(vbasedev->name,
  259. multifd->load_buf_idx);
  260. return true;
  261. }
  262. static bool vfio_load_bufs_thread_want_exit(VFIOMultifd *multifd,
  263. bool *should_quit)
  264. {
  265. return multifd->load_bufs_thread_want_exit || qatomic_read(should_quit);
  266. }
  267. /*
  268. * This thread is spawned by vfio_multifd_switchover_start() which gets
  269. * called upon encountering the switchover point marker in main migration
  270. * stream.
  271. *
  272. * It exits after either:
  273. * * completing loading the remaining device state and device config, OR:
  274. * * encountering some error while doing the above, OR:
  275. * * being forcefully aborted by the migration core by it setting should_quit
  276. * or by vfio_load_cleanup_load_bufs_thread() setting
  277. * multifd->load_bufs_thread_want_exit.
  278. */
  279. static bool vfio_load_bufs_thread(void *opaque, bool *should_quit, Error **errp)
  280. {
  281. VFIODevice *vbasedev = opaque;
  282. VFIOMigration *migration = vbasedev->migration;
  283. VFIOMultifd *multifd = migration->multifd;
  284. bool ret = false;
  285. trace_vfio_load_bufs_thread_start(vbasedev->name);
  286. assert(multifd);
  287. QEMU_LOCK_GUARD(&multifd->load_bufs_mutex);
  288. assert(multifd->load_bufs_thread_running);
  289. while (true) {
  290. VFIOStateBuffer *lb;
  291. /*
  292. * Always check cancellation first after the buffer_ready wait below in
  293. * case that cond was signalled by vfio_load_cleanup_load_bufs_thread().
  294. */
  295. if (vfio_load_bufs_thread_want_exit(multifd, should_quit)) {
  296. error_setg(errp, "operation cancelled");
  297. goto thread_exit;
  298. }
  299. assert(multifd->load_buf_idx <= multifd->load_buf_idx_last);
  300. lb = vfio_load_state_buffer_get(multifd);
  301. if (!lb) {
  302. trace_vfio_load_state_device_buffer_starved(vbasedev->name,
  303. multifd->load_buf_idx);
  304. qemu_cond_wait(&multifd->load_bufs_buffer_ready_cond,
  305. &multifd->load_bufs_mutex);
  306. continue;
  307. }
  308. if (multifd->load_buf_idx == multifd->load_buf_idx_last) {
  309. break;
  310. }
  311. if (multifd->load_buf_idx == 0) {
  312. trace_vfio_load_state_device_buffer_start(vbasedev->name);
  313. }
  314. if (!vfio_load_state_buffer_write(vbasedev, lb, errp)) {
  315. goto thread_exit;
  316. }
  317. if (multifd->load_buf_idx == multifd->load_buf_idx_last - 1) {
  318. trace_vfio_load_state_device_buffer_end(vbasedev->name);
  319. }
  320. multifd->load_buf_idx++;
  321. }
  322. if (!vfio_load_bufs_thread_load_config(vbasedev, errp)) {
  323. goto thread_exit;
  324. }
  325. ret = true;
  326. thread_exit:
  327. /*
  328. * Notify possibly waiting vfio_load_cleanup_load_bufs_thread() that
  329. * this thread is exiting.
  330. */
  331. multifd->load_bufs_thread_running = false;
  332. qemu_cond_signal(&multifd->load_bufs_thread_finished_cond);
  333. trace_vfio_load_bufs_thread_end(vbasedev->name);
  334. return ret;
  335. }
  336. static VFIOMultifd *vfio_multifd_new(void)
  337. {
  338. VFIOMultifd *multifd = g_new(VFIOMultifd, 1);
  339. vfio_state_buffers_init(&multifd->load_bufs);
  340. qemu_mutex_init(&multifd->load_bufs_mutex);
  341. multifd->load_buf_idx = 0;
  342. multifd->load_buf_idx_last = UINT32_MAX;
  343. qemu_cond_init(&multifd->load_bufs_buffer_ready_cond);
  344. multifd->load_bufs_thread_running = false;
  345. multifd->load_bufs_thread_want_exit = false;
  346. qemu_cond_init(&multifd->load_bufs_thread_finished_cond);
  347. return multifd;
  348. }
  349. /*
  350. * Terminates vfio_load_bufs_thread by setting
  351. * multifd->load_bufs_thread_want_exit and signalling all the conditions
  352. * the thread could be blocked on.
  353. *
  354. * Waits for the thread to signal that it had finished.
  355. */
  356. static void vfio_load_cleanup_load_bufs_thread(VFIOMultifd *multifd)
  357. {
  358. /* The lock order is load_bufs_mutex -> BQL so unlock BQL here first */
  359. bql_unlock();
  360. WITH_QEMU_LOCK_GUARD(&multifd->load_bufs_mutex) {
  361. while (multifd->load_bufs_thread_running) {
  362. multifd->load_bufs_thread_want_exit = true;
  363. qemu_cond_signal(&multifd->load_bufs_buffer_ready_cond);
  364. qemu_cond_wait(&multifd->load_bufs_thread_finished_cond,
  365. &multifd->load_bufs_mutex);
  366. }
  367. }
  368. bql_lock();
  369. }
  370. static void vfio_multifd_free(VFIOMultifd *multifd)
  371. {
  372. vfio_load_cleanup_load_bufs_thread(multifd);
  373. qemu_cond_destroy(&multifd->load_bufs_thread_finished_cond);
  374. vfio_state_buffers_destroy(&multifd->load_bufs);
  375. qemu_cond_destroy(&multifd->load_bufs_buffer_ready_cond);
  376. qemu_mutex_destroy(&multifd->load_bufs_mutex);
  377. g_free(multifd);
  378. }
  379. void vfio_multifd_cleanup(VFIODevice *vbasedev)
  380. {
  381. VFIOMigration *migration = vbasedev->migration;
  382. g_clear_pointer(&migration->multifd, vfio_multifd_free);
  383. }
  384. bool vfio_multifd_transfer_supported(void)
  385. {
  386. return multifd_device_state_supported() &&
  387. migrate_send_switchover_start();
  388. }
  389. bool vfio_multifd_transfer_enabled(VFIODevice *vbasedev)
  390. {
  391. VFIOMigration *migration = vbasedev->migration;
  392. return migration->multifd_transfer;
  393. }
  394. bool vfio_multifd_setup(VFIODevice *vbasedev, bool alloc_multifd, Error **errp)
  395. {
  396. VFIOMigration *migration = vbasedev->migration;
  397. /*
  398. * Make a copy of this setting at the start in case it is changed
  399. * mid-migration.
  400. */
  401. if (vbasedev->migration_multifd_transfer == ON_OFF_AUTO_AUTO) {
  402. migration->multifd_transfer = vfio_multifd_transfer_supported();
  403. } else {
  404. migration->multifd_transfer =
  405. vbasedev->migration_multifd_transfer == ON_OFF_AUTO_ON;
  406. }
  407. if (!vfio_multifd_transfer_enabled(vbasedev)) {
  408. /* Nothing further to check or do */
  409. return true;
  410. }
  411. if (!vfio_multifd_transfer_supported()) {
  412. error_setg(errp,
  413. "%s: Multifd device transfer requested but unsupported in the current config",
  414. vbasedev->name);
  415. return false;
  416. }
  417. if (alloc_multifd) {
  418. assert(!migration->multifd);
  419. migration->multifd = vfio_multifd_new();
  420. }
  421. return true;
  422. }
  423. void vfio_multifd_emit_dummy_eos(VFIODevice *vbasedev, QEMUFile *f)
  424. {
  425. assert(vfio_multifd_transfer_enabled(vbasedev));
  426. /*
  427. * Emit dummy NOP data on the main migration channel since the actual
  428. * device state transfer is done via multifd channels.
  429. */
  430. qemu_put_be64(f, VFIO_MIG_FLAG_END_OF_STATE);
  431. }
  432. static bool
  433. vfio_save_complete_precopy_thread_config_state(VFIODevice *vbasedev,
  434. char *idstr,
  435. uint32_t instance_id,
  436. uint32_t idx,
  437. Error **errp)
  438. {
  439. g_autoptr(QIOChannelBuffer) bioc = NULL;
  440. g_autoptr(QEMUFile) f = NULL;
  441. int ret;
  442. g_autofree VFIODeviceStatePacket *packet = NULL;
  443. size_t packet_len;
  444. bioc = qio_channel_buffer_new(0);
  445. qio_channel_set_name(QIO_CHANNEL(bioc), "vfio-device-config-save");
  446. f = qemu_file_new_output(QIO_CHANNEL(bioc));
  447. if (vfio_save_device_config_state(f, vbasedev, errp)) {
  448. return false;
  449. }
  450. ret = qemu_fflush(f);
  451. if (ret) {
  452. error_setg(errp, "%s: save config state flush failed: %d",
  453. vbasedev->name, ret);
  454. return false;
  455. }
  456. packet_len = sizeof(*packet) + bioc->usage;
  457. packet = g_malloc0(packet_len);
  458. packet->version = cpu_to_be32(VFIO_DEVICE_STATE_PACKET_VER_CURRENT);
  459. packet->idx = cpu_to_be32(idx);
  460. packet->flags = cpu_to_be32(VFIO_DEVICE_STATE_CONFIG_STATE);
  461. memcpy(&packet->data, bioc->data, bioc->usage);
  462. if (!multifd_queue_device_state(idstr, instance_id,
  463. (char *)packet, packet_len)) {
  464. error_setg(errp, "%s: multifd config data queuing failed",
  465. vbasedev->name);
  466. return false;
  467. }
  468. vfio_mig_add_bytes_transferred(packet_len);
  469. return true;
  470. }
  471. /*
  472. * This thread is spawned by the migration core directly via
  473. * .save_live_complete_precopy_thread SaveVMHandler.
  474. *
  475. * It exits after either:
  476. * * completing saving the remaining device state and device config, OR:
  477. * * encountering some error while doing the above, OR:
  478. * * being forcefully aborted by the migration core by
  479. * multifd_device_state_save_thread_should_exit() returning true.
  480. */
  481. bool
  482. vfio_multifd_save_complete_precopy_thread(SaveLiveCompletePrecopyThreadData *d,
  483. Error **errp)
  484. {
  485. VFIODevice *vbasedev = d->handler_opaque;
  486. VFIOMigration *migration = vbasedev->migration;
  487. bool ret = false;
  488. g_autofree VFIODeviceStatePacket *packet = NULL;
  489. uint32_t idx;
  490. if (!vfio_multifd_transfer_enabled(vbasedev)) {
  491. /* Nothing to do, vfio_save_complete_precopy() does the transfer. */
  492. return true;
  493. }
  494. trace_vfio_save_complete_precopy_thread_start(vbasedev->name,
  495. d->idstr, d->instance_id);
  496. /* We reach here with device state STOP or STOP_COPY only */
  497. if (vfio_migration_set_state(vbasedev, VFIO_DEVICE_STATE_STOP_COPY,
  498. VFIO_DEVICE_STATE_STOP, errp)) {
  499. goto thread_exit;
  500. }
  501. packet = g_malloc0(sizeof(*packet) + migration->data_buffer_size);
  502. packet->version = cpu_to_be32(VFIO_DEVICE_STATE_PACKET_VER_CURRENT);
  503. for (idx = 0; ; idx++) {
  504. ssize_t data_size;
  505. size_t packet_size;
  506. if (multifd_device_state_save_thread_should_exit()) {
  507. error_setg(errp, "operation cancelled");
  508. goto thread_exit;
  509. }
  510. data_size = read(migration->data_fd, &packet->data,
  511. migration->data_buffer_size);
  512. if (data_size < 0) {
  513. error_setg(errp, "%s: reading state buffer %" PRIu32 " failed: %d",
  514. vbasedev->name, idx, errno);
  515. goto thread_exit;
  516. } else if (data_size == 0) {
  517. break;
  518. }
  519. packet->idx = cpu_to_be32(idx);
  520. packet_size = sizeof(*packet) + data_size;
  521. if (!multifd_queue_device_state(d->idstr, d->instance_id,
  522. (char *)packet, packet_size)) {
  523. error_setg(errp, "%s: multifd data queuing failed", vbasedev->name);
  524. goto thread_exit;
  525. }
  526. vfio_mig_add_bytes_transferred(packet_size);
  527. }
  528. if (!vfio_save_complete_precopy_thread_config_state(vbasedev,
  529. d->idstr,
  530. d->instance_id,
  531. idx, errp)) {
  532. goto thread_exit;
  533. }
  534. ret = true;
  535. thread_exit:
  536. trace_vfio_save_complete_precopy_thread_end(vbasedev->name, ret);
  537. return ret;
  538. }
  539. int vfio_multifd_switchover_start(VFIODevice *vbasedev)
  540. {
  541. VFIOMigration *migration = vbasedev->migration;
  542. VFIOMultifd *multifd = migration->multifd;
  543. assert(multifd);
  544. /* The lock order is load_bufs_mutex -> BQL so unlock BQL here first */
  545. bql_unlock();
  546. WITH_QEMU_LOCK_GUARD(&multifd->load_bufs_mutex) {
  547. assert(!multifd->load_bufs_thread_running);
  548. multifd->load_bufs_thread_running = true;
  549. }
  550. bql_lock();
  551. qemu_loadvm_start_load_thread(vfio_load_bufs_thread, vbasedev);
  552. return 0;
  553. }