[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 20/28] migration/postcopy: enable compress during postcopy
From: |
Juan Quintela |
Subject: |
[PULL 20/28] migration/postcopy: enable compress during postcopy |
Date: |
Fri, 10 Jan 2020 18:32:07 +0100 |
From: Wei Yang <address@hidden>
postcopy requires to place a whole host page, while migration thread
migrate memory in target page size. This makes postcopy need to collect
all target pages in one host page before placing via userfaultfd.
To enable compress during postcopy, there are two problems to solve:
1. Random order for target page arrival
2. Target pages in one host page arrives without interrupt by target
page from other host page
The first one is handled by previous cleanup patch.
This patch handles the second one by:
1. Flush compress thread for each host page
2. Wait for decompress thread for before placing host page
Signed-off-by: Wei Yang <address@hidden>
Reviewed-by: Dr. David Alan Gilbert <address@hidden>
Reviewed-by: Juan Quintela <address@hidden>
Signed-off-by: Juan Quintela <address@hidden>
---
migration/migration.c | 11 -----------
migration/ram.c | 28 +++++++++++++++++++++++++++-
2 files changed, 27 insertions(+), 12 deletions(-)
diff --git a/migration/migration.c b/migration/migration.c
index e55edee606..990bff00c0 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -1005,17 +1005,6 @@ static bool migrate_caps_check(bool *cap_list,
#endif
if (cap_list[MIGRATION_CAPABILITY_POSTCOPY_RAM]) {
- if (cap_list[MIGRATION_CAPABILITY_COMPRESS]) {
- /* The decompression threads asynchronously write into RAM
- * rather than use the atomic copies needed to avoid
- * userfaulting. It should be possible to fix the decompression
- * threads for compatibility in future.
- */
- error_setg(errp, "Postcopy is not currently compatible "
- "with compression");
- return false;
- }
-
/* This check is reasonably expensive, so only when it's being
* set the first time, also it's only the destination that needs
* special support.
diff --git a/migration/ram.c b/migration/ram.c
index b5546940f9..b9eb08f549 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -3469,6 +3469,14 @@ static int ram_save_iterate(QEMUFile *f, void *opaque)
rs->target_page_count += pages;
+ /*
+ * During postcopy, it is necessary to make sure one whole host
+ * page is sent in one chunk.
+ */
+ if (migrate_postcopy_ram()) {
+ flush_compressed_data(rs);
+ }
+
/*
* we want to check in the 1st loop, just in case it was the 1st
* time and we had to sync the dirty bitmap.
@@ -4061,6 +4069,7 @@ static int ram_load_postcopy(QEMUFile *f)
void *place_source = NULL;
RAMBlock *block = NULL;
uint8_t ch;
+ int len;
addr = qemu_get_be64(f);
@@ -4078,7 +4087,8 @@ static int ram_load_postcopy(QEMUFile *f)
trace_ram_load_postcopy_loop((uint64_t)addr, flags);
place_needed = false;
- if (flags & (RAM_SAVE_FLAG_ZERO | RAM_SAVE_FLAG_PAGE)) {
+ if (flags & (RAM_SAVE_FLAG_ZERO | RAM_SAVE_FLAG_PAGE |
+ RAM_SAVE_FLAG_COMPRESS_PAGE)) {
block = ram_block_from_stream(f, flags);
host = host_from_ram_block_offset(block, addr);
@@ -4161,6 +4171,17 @@ static int ram_load_postcopy(QEMUFile *f)
TARGET_PAGE_SIZE);
}
break;
+ case RAM_SAVE_FLAG_COMPRESS_PAGE:
+ all_zero = false;
+ len = qemu_get_be32(f);
+ if (len < 0 || len > compressBound(TARGET_PAGE_SIZE)) {
+ error_report("Invalid compressed data length: %d", len);
+ ret = -EINVAL;
+ break;
+ }
+ decompress_data_with_multi_threads(f, page_buffer, len);
+ break;
+
case RAM_SAVE_FLAG_EOS:
/* normal exit */
multifd_recv_sync_main();
@@ -4172,6 +4193,11 @@ static int ram_load_postcopy(QEMUFile *f)
break;
}
+ /* Got the whole host page, wait for decompress before placing. */
+ if (place_needed) {
+ ret |= wait_for_decompress_done();
+ }
+
/* Detect for any possible file errors */
if (!ret && qemu_file_get_error(f)) {
ret = qemu_file_get_error(f);
--
2.24.1
- [PULL 11/28] misc: use QEMU_IS_ALIGNED, (continued)
- [PULL 11/28] misc: use QEMU_IS_ALIGNED, Juan Quintela, 2020/01/10
- [PULL 12/28] migration: add savevm_state_handler_remove(), Juan Quintela, 2020/01/10
- [PULL 10/28] migration: Fix the re-run check of the migrate-incoming command, Juan Quintela, 2020/01/10
- [PULL 13/28] migration: savevm_state_handler_insert: constant-time element insertion, Juan Quintela, 2020/01/10
- [PULL 14/28] migration/ram: Yield periodically to the main loop, Juan Quintela, 2020/01/10
- [PULL 15/28] migration/postcopy: reduce memset when it is zero page and matches_target_page_size, Juan Quintela, 2020/01/10
- [PULL 16/28] migration/postcopy: wait for decompress thread in precopy, Juan Quintela, 2020/01/10
- [PULL 17/28] migration/postcopy: count target page number to decide the place_needed, Juan Quintela, 2020/01/10
- [PULL 18/28] migration/postcopy: set all_zero to true on the first target page, Juan Quintela, 2020/01/10
- [PULL 19/28] migration/postcopy: enable random order target page arrival, Juan Quintela, 2020/01/10
- [PULL 20/28] migration/postcopy: enable compress during postcopy,
Juan Quintela <=
- [PULL 21/28] migration/multifd: clean pages after filling packet, Juan Quintela, 2020/01/10
- [PULL 22/28] migration/multifd: not use multifd during postcopy, Juan Quintela, 2020/01/10
- [PULL 23/28] migration/multifd: fix nullptr access in terminating multifd threads, Juan Quintela, 2020/01/10
- [PULL 24/28] migration/multifd: fix destroyed mutex access in terminating multifd threads, Juan Quintela, 2020/01/10
- [PULL 25/28] Bug #1829242 correction., Juan Quintela, 2020/01/10
- [PULL 26/28] migration: Define VMSTATE_INSTANCE_ID_ANY, Juan Quintela, 2020/01/10
- [PULL 27/28] migration: Change SaveStateEntry.instance_id into uint32_t, Juan Quintela, 2020/01/10
- [PULL 28/28] apic: Use 32bit APIC ID for migration instance ID, Juan Quintela, 2020/01/10
- Re: [PULL 00/28] Migration pull patches, Peter Maydell, 2020/01/13