[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[RFC PATCH v1 12/26] migration: Add support for 'fixed-ram' migration re
From: |
Fabiano Rosas |
Subject: |
[RFC PATCH v1 12/26] migration: Add support for 'fixed-ram' migration restore |
Date: |
Thu, 30 Mar 2023 15:03:22 -0300 |
From: Nikolay Borisov <nborisov@suse.com>
Add the necessary code to parse the format changes for the 'fixed-ram'
capability.
One of the more notable changes in behavior is that in the 'fixed-ram'
case ram pages are restored in one go rather than constantly looping
through the migration stream.
Also due to idiosyncrasies of the format I have added the
'ram_migrated' since it was easier to simply return directly from
->load_state rather than introducing more conditionals around the code
to prevent ->load_state being called multiple times (from
qemu_loadvm_section_start_full/qemu_loadvm_section_part_end i.e. from
multiple QEMU_VM_SECTION_(PART|END) flags).
Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
---
migration/migration.h | 2 +
migration/ram.c | 105 +++++++++++++++++++++++++++++++++++++++++-
2 files changed, 105 insertions(+), 2 deletions(-)
diff --git a/migration/migration.h b/migration/migration.h
index 8cf3caecfe..84be34587f 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -96,6 +96,8 @@ struct MigrationIncomingState {
bool have_listen_thread;
QemuThread listen_thread;
+ bool ram_migrated;
+
/* For the kernel to send us notifications */
int userfault_fd;
/* To notify the fault_thread to wake, e.g., when need to quit */
diff --git a/migration/ram.c b/migration/ram.c
index 5c085d6154..1666ce6d5f 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -4396,6 +4396,100 @@ static int parse_ramblocks(QEMUFile *f, ram_addr_t
total_ram_bytes)
return ret;
}
+static void read_ramblock_fixed_ram(QEMUFile *f, RAMBlock *block,
+ long num_pages, unsigned long *bitmap)
+{
+ unsigned long set_bit_idx, clear_bit_idx;
+ unsigned long len;
+ ram_addr_t offset;
+ void *host;
+ size_t read, completed, read_len;
+
+ for (set_bit_idx = find_first_bit(bitmap, num_pages);
+ set_bit_idx < num_pages;
+ set_bit_idx = find_next_bit(bitmap, num_pages, clear_bit_idx + 1)) {
+
+ clear_bit_idx = find_next_zero_bit(bitmap, num_pages, set_bit_idx + 1);
+
+ len = TARGET_PAGE_SIZE * (clear_bit_idx - set_bit_idx);
+ offset = set_bit_idx << TARGET_PAGE_BITS;
+
+ for (read = 0, completed = 0; completed < len; offset += read) {
+ host = host_from_ram_block_offset(block, offset);
+ read_len = MIN(len, TARGET_PAGE_SIZE);
+
+ read = qemu_get_buffer_at(f, host, read_len,
+ block->pages_offset + offset);
+ completed += read;
+ }
+ }
+}
+
+static int parse_ramblocks_fixed_ram(QEMUFile *f)
+{
+ int ret = 0;
+
+ while (!ret) {
+ char id[256];
+ RAMBlock *block;
+ ram_addr_t length;
+ long num_pages, bitmap_size;
+ int len = qemu_get_byte(f);
+ g_autofree unsigned long *dirty_bitmap = NULL;
+
+ qemu_get_buffer(f, (uint8_t *)id, len);
+ id[len] = 0;
+ length = qemu_get_be64(f);
+
+ block = qemu_ram_block_by_name(id);
+ if (block) {
+ ret = parse_ramblock(f, block, length);
+ if (ret < 0) {
+ return ret;
+ }
+ } else {
+ error_report("Unknown ramblock \"%s\", cannot accept "
+ "migration", id);
+ ret = -EINVAL;
+ continue;
+ }
+
+ /* 1. read the bitmap size */
+ num_pages = length >> TARGET_PAGE_BITS;
+ bitmap_size = qemu_get_be32(f);
+
+ assert(bitmap_size == BITS_TO_LONGS(num_pages) * sizeof(unsigned
long));
+
+ block->pages_offset = qemu_get_be64(f);
+
+ /* 2. read the actual bitmap */
+ dirty_bitmap = g_malloc0(bitmap_size);
+ if (qemu_get_buffer(f, (uint8_t *)dirty_bitmap, bitmap_size) !=
bitmap_size) {
+ error_report("Error parsing dirty bitmap");
+ return -EINVAL;
+ }
+
+ read_ramblock_fixed_ram(f, block, num_pages, dirty_bitmap);
+
+ /* Skip pages array */
+ qemu_set_offset(f, block->pages_offset + length, SEEK_SET);
+
+ /* Check if this is the last ramblock */
+ if (qemu_get_be64(f) == RAM_SAVE_FLAG_EOS) {
+ ret = 1;
+ } else {
+ /*
+ * If not, adjust the internal file index to account for the
+ * previous 64 bit read
+ */
+ qemu_file_skip(f, -8);
+ ret = 0;
+ }
+ }
+
+ return ret;
+}
+
/**
* ram_load_precopy: load pages in precopy case
*
@@ -4415,7 +4509,7 @@ static int ram_load_precopy(QEMUFile *f)
invalid_flags |= RAM_SAVE_FLAG_COMPRESS_PAGE;
}
- while (!ret && !(flags & RAM_SAVE_FLAG_EOS)) {
+ while (!ret && !(flags & RAM_SAVE_FLAG_EOS) && !mis->ram_migrated) {
ram_addr_t addr;
void *host = NULL, *host_bak = NULL;
uint8_t ch;
@@ -4487,7 +4581,14 @@ static int ram_load_precopy(QEMUFile *f)
switch (flags & ~RAM_SAVE_FLAG_CONTINUE) {
case RAM_SAVE_FLAG_MEM_SIZE:
- ret = parse_ramblocks(f, addr);
+ if (migrate_fixed_ram()) {
+ ret = parse_ramblocks_fixed_ram(f);
+ if (ret == 1) {
+ mis->ram_migrated = true;
+ }
+ } else {
+ ret = parse_ramblocks(f, addr);
+ }
break;
case RAM_SAVE_FLAG_ZERO:
--
2.35.3
- [RFC PATCH v1 04/26] tests/qtest: migration-test: Add tests for file-based migration, (continued)
- [RFC PATCH v1 04/26] tests/qtest: migration-test: Add tests for file-based migration, Fabiano Rosas, 2023/03/30
- [RFC PATCH v1 01/26] migration: Add support for 'file:' uri for source migration, Fabiano Rosas, 2023/03/30
- [RFC PATCH v1 03/26] tests/qtest: migration: Add migrate_incoming_qmp helper, Fabiano Rosas, 2023/03/30
- [RFC PATCH v1 05/26] migration: Initial support of fixed-ram feature for analyze-migration.py, Fabiano Rosas, 2023/03/30
- [RFC PATCH v1 06/26] io: add and implement QIO_CHANNEL_FEATURE_SEEKABLE for channel file, Fabiano Rosas, 2023/03/30
- [RFC PATCH v1 08/26] io: implement io_pwritev/preadv for QIOChannelFile, Fabiano Rosas, 2023/03/30
- [RFC PATCH v1 07/26] io: Add generic pwritev/preadv interface, Fabiano Rosas, 2023/03/30
- [RFC PATCH v1 09/26] migration/qemu-file: add utility methods for working with seekable channels, Fabiano Rosas, 2023/03/30
- [RFC PATCH v1 10/26] migration/ram: Introduce 'fixed-ram' migration stream capability, Fabiano Rosas, 2023/03/30
- [RFC PATCH v1 11/26] migration: Refactor precopy ram loading code, Fabiano Rosas, 2023/03/30
- [RFC PATCH v1 12/26] migration: Add support for 'fixed-ram' migration restore,
Fabiano Rosas <=
- [RFC PATCH v1 13/26] tests/qtest: migration-test: Add tests for fixed-ram file-based migration, Fabiano Rosas, 2023/03/30
- [RFC PATCH v1 15/26] migration/multifd: Remove direct "socket" references, Fabiano Rosas, 2023/03/30
- [RFC PATCH v1 14/26] migration: Add completion tracepoint, Fabiano Rosas, 2023/03/30
- [RFC PATCH v1 16/26] migration/multifd: Allow multifd without packets, Fabiano Rosas, 2023/03/30
- [RFC PATCH v1 17/26] migration/multifd: Add outgoing QIOChannelFile support, Fabiano Rosas, 2023/03/30
- [RFC PATCH v1 19/26] migration/multifd: Add pages to the receiving side, Fabiano Rosas, 2023/03/30
- [RFC PATCH v1 18/26] migration/multifd: Add incoming QIOChannelFile support, Fabiano Rosas, 2023/03/30
- [RFC PATCH v1 21/26] migration/ram: Add a wrapper for fixed-ram shadow bitmap, Fabiano Rosas, 2023/03/30
- [RFC PATCH v1 22/26] migration/multifd: Support outgoing fixed-ram stream format, Fabiano Rosas, 2023/03/30
- [RFC PATCH v1 20/26] io: Add a pwritev/preadv version that takes a discontiguous iovec, Fabiano Rosas, 2023/03/30