summaryrefslogtreecommitdiff
path: root/migration/postcopy-ram.c
diff options
context:
space:
mode:
authorDr. David Alan Gilbert <dgilbert@redhat.com>2017-02-24 18:28:36 +0000
committerDr. David Alan Gilbert <dgilbert@redhat.com>2017-02-28 11:30:23 +0000
commit41d84210d403a686052fb5fc4c9f027e13e92185 (patch)
tree2d31a0130c4b60b9e0a2dece43d16b43e1de32bc /migration/postcopy-ram.c
parentdf9ff5e1e37982e666216fe9a324d118a30f178f (diff)
downloadqemu-41d84210d403a686052fb5fc4c9f027e13e92185.tar.gz
postcopy: Use temporary for placing zero huge pages
The kernel can't do UFFDIO_ZEROPAGE for huge pages, so we have to allocate a temporary (always zero) page and use UFFDIO_COPYPAGE on it. Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com> Reviewed-by: Juan Quintela <quintela@redhat.com> Reviewed-by: Laurent Vivier <lvivier@redhat.com> Message-Id: <20170224182844.32452-9-dgilbert@redhat.com> Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Diffstat (limited to 'migration/postcopy-ram.c')
-rw-r--r--migration/postcopy-ram.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c
index a8b7fedc99..4c736d28a0 100644
--- a/migration/postcopy-ram.c
+++ b/migration/postcopy-ram.c
@@ -324,6 +324,10 @@ int postcopy_ram_incoming_cleanup(MigrationIncomingState *mis)
munmap(mis->postcopy_tmp_page, mis->largest_page_size);
mis->postcopy_tmp_page = NULL;
}
+ if (mis->postcopy_tmp_zero_page) {
+ munmap(mis->postcopy_tmp_zero_page, mis->largest_page_size);
+ mis->postcopy_tmp_zero_page = NULL;
+ }
trace_postcopy_ram_incoming_cleanup_exit();
return 0;
}
@@ -593,8 +597,23 @@ int postcopy_place_page_zero(MigrationIncomingState *mis, void *host,
return -e;
}
} else {
- /* TODO: The kernel can't use UFFDIO_ZEROPAGE for hugepages */
- assert(0);
+ /* The kernel can't use UFFDIO_ZEROPAGE for hugepages */
+ if (!mis->postcopy_tmp_zero_page) {
+ mis->postcopy_tmp_zero_page = mmap(NULL, mis->largest_page_size,
+ PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS,
+ -1, 0);
+ if (mis->postcopy_tmp_zero_page == MAP_FAILED) {
+ int e = errno;
+ mis->postcopy_tmp_zero_page = NULL;
+ error_report("%s: %s mapping large zero page",
+ __func__, strerror(e));
+ return -e;
+ }
+ memset(mis->postcopy_tmp_zero_page, '\0', mis->largest_page_size);
+ }
+ return postcopy_place_page(mis, host, mis->postcopy_tmp_zero_page,
+ pagesize);
}
return 0;