From 1d7414396f926651c4d7a673eb3a10aca5246d76 Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" Date: Thu, 19 Nov 2015 15:27:48 +0000 Subject: [PATCH 1/2] Assume madvise for (no)hugepage works madvise() returns EINVAL in the case of many failures, but also returns it in cases where the host kernel doesn't have THP enabled. Postcopy only really cares that THP is off before it detects faults, and turns it back on afterwards; so we're going to have to assume that if the madvise fails then the host just doesn't do THP and we can carry on with the postcopy. Signed-off-by: Dr. David Alan Gilbert Tested-by: Jason J. Herne Reviewed-by: Juan Quintela Reviewed-by: Amit Shah Signed-off-by: Juan Quintela --- migration/postcopy-ram.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c index 22d6b18e63..3946aa98aa 100644 --- a/migration/postcopy-ram.c +++ b/migration/postcopy-ram.c @@ -241,10 +241,7 @@ static int cleanup_range(const char *block_name, void *host_addr, * We turned off hugepage for the precopy stage with postcopy enabled * we can turn it back on now. */ - if (qemu_madvise(host_addr, length, QEMU_MADV_HUGEPAGE)) { - error_report("%s HUGEPAGE: %s", __func__, strerror(errno)); - return -1; - } + qemu_madvise(host_addr, length, QEMU_MADV_HUGEPAGE); /* * We can also turn off userfault now since we should have all the @@ -345,10 +342,7 @@ static int nhp_range(const char *block_name, void *host_addr, * do delete areas of the page, even if THP thinks a hugepage would * be a good idea, so force hugepages off. */ - if (qemu_madvise(host_addr, length, QEMU_MADV_NOHUGEPAGE)) { - error_report("%s: NOHUGEPAGE: %s", __func__, strerror(errno)); - return -1; - } + qemu_madvise(host_addr, length, QEMU_MADV_NOHUGEPAGE); return 0; } From f77dcdbc76dbf9bade9739e85e1013639e535835 Mon Sep 17 00:00:00 2001 From: Wen Congyang Date: Fri, 20 Nov 2015 17:37:13 +0800 Subject: [PATCH 2/2] block-migration: limit the memory usage If we set migration speed in a very large value, block-migration will try to read all data to the memory. Because (block_mig_state.submitted + block_mig_state.read_done) * BLOCK_SIZE will be overflow, and it will be always less than rate limit. There is no need to read too many data into memory when the rate limit is very large. So limit the memory usage can fix the overflow problem. Signed-off-by: Wen Congyang Reviewed-by: Juan Quintela Reviewed-by: Stefan Hajnoczi Signed-off-by: Juan Quintela --- migration/block.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/migration/block.c b/migration/block.c index 310e2b36dc..656f38f341 100644 --- a/migration/block.c +++ b/migration/block.c @@ -36,6 +36,8 @@ #define MAX_IS_ALLOCATED_SEARCH 65536 +#define MAX_INFLIGHT_IO 512 + //#define DEBUG_BLK_MIGRATION #ifdef DEBUG_BLK_MIGRATION @@ -665,7 +667,10 @@ static int block_save_iterate(QEMUFile *f, void *opaque) blk_mig_lock(); while ((block_mig_state.submitted + block_mig_state.read_done) * BLOCK_SIZE < - qemu_file_get_rate_limit(f)) { + qemu_file_get_rate_limit(f) && + (block_mig_state.submitted + + block_mig_state.read_done) < + MAX_INFLIGHT_IO) { blk_mig_unlock(); if (block_mig_state.bulk_completed == 0) { /* first finish the bulk phase */