summaryrefslogtreecommitdiff
path: root/migration/ram.c
diff options
context:
space:
mode:
authorPavel Butsykin <pbutsykin@virtuozzo.com>2017-02-03 18:23:20 +0300
committerDr. David Alan Gilbert <dgilbert@redhat.com>2017-02-13 17:27:13 +0000
commit53f09a1076f5efbba7d751a8005e2fcf008606db (patch)
tree1f4f0cd62537a1f1b50ca73fcba8fb3ee7a272d0 /migration/ram.c
parent9eb14766102b7af5c3ab3d64cc85985bdaa544e2 (diff)
downloadqemu-53f09a1076f5efbba7d751a8005e2fcf008606db.tar.gz
add 'release-ram' migrate capability
This feature frees the migrated memory on the source during postcopy-ram migration. In the second step of postcopy-ram migration when the source vm is put on pause we can free unnecessary memory. It will allow, in particular, to start relaxing the memory stress on the source host in a load-balancing scenario. Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com> Message-Id: <20170203152321.19739-3-pbutsykin@virtuozzo.com> Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com> Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com> Manually merged in Pavel's 'migration: madvise error_report fixup!'
Diffstat (limited to 'migration/ram.c')
-rw-r--r--migration/ram.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/migration/ram.c b/migration/ram.c
index 91443b3961..c22209db30 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -705,6 +705,16 @@ static int save_zero_page(QEMUFile *f, RAMBlock *block, ram_addr_t offset,
return pages;
}
+static void ram_release_pages(MigrationState *ms, const char *block_name,
+ uint64_t offset, int pages)
+{
+ if (!migrate_release_ram() || !migration_in_postcopy(ms)) {
+ return;
+ }
+
+ ram_discard_range(NULL, block_name, offset, pages << TARGET_PAGE_BITS);
+}
+
/**
* ram_save_page: Send the given page to the stream
*
@@ -765,6 +775,7 @@ static int ram_save_page(MigrationState *ms, QEMUFile *f, PageSearchStatus *pss,
* page would be stale
*/
xbzrle_cache_zero_page(current_addr);
+ ram_release_pages(ms, block->idstr, pss->offset, pages);
} else if (!ram_bulk_stage &&
!migration_in_postcopy(ms) && migrate_use_xbzrle()) {
pages = save_xbzrle_page(f, &p, current_addr, block,
@@ -783,7 +794,9 @@ static int ram_save_page(MigrationState *ms, QEMUFile *f, PageSearchStatus *pss,
*bytes_transferred += save_page_header(f, block,
offset | RAM_SAVE_FLAG_PAGE);
if (send_async) {
- qemu_put_buffer_async(f, p, TARGET_PAGE_SIZE);
+ qemu_put_buffer_async(f, p, TARGET_PAGE_SIZE,
+ migrate_release_ram() &
+ migration_in_postcopy(ms));
} else {
qemu_put_buffer(f, p, TARGET_PAGE_SIZE);
}
@@ -813,6 +826,8 @@ static int do_compress_ram_page(QEMUFile *f, RAMBlock *block,
error_report("compressed data failed!");
} else {
bytes_sent += blen;
+ ram_release_pages(migrate_get_current(), block->idstr,
+ offset & TARGET_PAGE_MASK, 1);
}
return bytes_sent;
@@ -952,12 +967,17 @@ static int ram_save_compressed_page(MigrationState *ms, QEMUFile *f,
error_report("compressed data failed!");
}
}
+ if (pages > 0) {
+ ram_release_pages(ms, block->idstr, pss->offset, pages);
+ }
} else {
offset |= RAM_SAVE_FLAG_CONTINUE;
pages = save_zero_page(f, block, offset, p, bytes_transferred);
if (pages == -1) {
pages = compress_page_with_multi_thread(f, block, offset,
bytes_transferred);
+ } else {
+ ram_release_pages(ms, block->idstr, pss->offset, pages);
}
}
}