提交 df9ff5e1 编写于 作者: D Dr. David Alan Gilbert

postcopy: Plumb pagesize down into place helpers

Now we deal with normal size pages and huge pages we need
to tell the place handlers the size we're dealing with
and make sure the temporary page is large enough.
Signed-off-by: NDr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: NJuan Quintela <quintela@redhat.com>
Reviewed-by: NLaurent Vivier <lvivier@redhat.com>
Message-Id: <20170224182844.32452-8-dgilbert@redhat.com>
Signed-off-by: NDr. David Alan Gilbert <dgilbert@redhat.com>
上级 67f11b5c
...@@ -74,13 +74,15 @@ void postcopy_discard_send_finish(MigrationState *ms, ...@@ -74,13 +74,15 @@ void postcopy_discard_send_finish(MigrationState *ms,
* to use other postcopy_ routines to allocate. * to use other postcopy_ routines to allocate.
* returns 0 on success * returns 0 on success
*/ */
int postcopy_place_page(MigrationIncomingState *mis, void *host, void *from); int postcopy_place_page(MigrationIncomingState *mis, void *host, void *from,
size_t pagesize);
/* /*
* Place a zero page at (host) atomically * Place a zero page at (host) atomically
* returns 0 on success * returns 0 on success
*/ */
int postcopy_place_page_zero(MigrationIncomingState *mis, void *host); int postcopy_place_page_zero(MigrationIncomingState *mis, void *host,
size_t pagesize);
/* /*
* Allocate a page of memory that can be mapped at a later point in time * Allocate a page of memory that can be mapped at a later point in time
......
...@@ -321,7 +321,7 @@ int postcopy_ram_incoming_cleanup(MigrationIncomingState *mis) ...@@ -321,7 +321,7 @@ int postcopy_ram_incoming_cleanup(MigrationIncomingState *mis)
migrate_send_rp_shut(mis, qemu_file_get_error(mis->from_src_file) != 0); migrate_send_rp_shut(mis, qemu_file_get_error(mis->from_src_file) != 0);
if (mis->postcopy_tmp_page) { if (mis->postcopy_tmp_page) {
munmap(mis->postcopy_tmp_page, getpagesize()); munmap(mis->postcopy_tmp_page, mis->largest_page_size);
mis->postcopy_tmp_page = NULL; mis->postcopy_tmp_page = NULL;
} }
trace_postcopy_ram_incoming_cleanup_exit(); trace_postcopy_ram_incoming_cleanup_exit();
...@@ -543,13 +543,14 @@ int postcopy_ram_enable_notify(MigrationIncomingState *mis) ...@@ -543,13 +543,14 @@ int postcopy_ram_enable_notify(MigrationIncomingState *mis)
* Place a host page (from) at (host) atomically * Place a host page (from) at (host) atomically
* returns 0 on success * returns 0 on success
*/ */
int postcopy_place_page(MigrationIncomingState *mis, void *host, void *from) int postcopy_place_page(MigrationIncomingState *mis, void *host, void *from,
size_t pagesize)
{ {
struct uffdio_copy copy_struct; struct uffdio_copy copy_struct;
copy_struct.dst = (uint64_t)(uintptr_t)host; copy_struct.dst = (uint64_t)(uintptr_t)host;
copy_struct.src = (uint64_t)(uintptr_t)from; copy_struct.src = (uint64_t)(uintptr_t)from;
copy_struct.len = getpagesize(); copy_struct.len = pagesize;
copy_struct.mode = 0; copy_struct.mode = 0;
/* copy also acks to the kernel waking the stalled thread up /* copy also acks to the kernel waking the stalled thread up
...@@ -559,8 +560,8 @@ int postcopy_place_page(MigrationIncomingState *mis, void *host, void *from) ...@@ -559,8 +560,8 @@ int postcopy_place_page(MigrationIncomingState *mis, void *host, void *from)
*/ */
if (ioctl(mis->userfault_fd, UFFDIO_COPY, &copy_struct)) { if (ioctl(mis->userfault_fd, UFFDIO_COPY, &copy_struct)) {
int e = errno; int e = errno;
error_report("%s: %s copy host: %p from: %p", error_report("%s: %s copy host: %p from: %p (size: %zd)",
__func__, strerror(e), host, from); __func__, strerror(e), host, from, pagesize);
return -e; return -e;
} }
...@@ -573,23 +574,29 @@ int postcopy_place_page(MigrationIncomingState *mis, void *host, void *from) ...@@ -573,23 +574,29 @@ int postcopy_place_page(MigrationIncomingState *mis, void *host, void *from)
* Place a zero page at (host) atomically * Place a zero page at (host) atomically
* returns 0 on success * returns 0 on success
*/ */
int postcopy_place_page_zero(MigrationIncomingState *mis, void *host) int postcopy_place_page_zero(MigrationIncomingState *mis, void *host,
size_t pagesize)
{ {
struct uffdio_zeropage zero_struct; trace_postcopy_place_page_zero(host);
zero_struct.range.start = (uint64_t)(uintptr_t)host; if (pagesize == getpagesize()) {
zero_struct.range.len = getpagesize(); struct uffdio_zeropage zero_struct;
zero_struct.mode = 0; zero_struct.range.start = (uint64_t)(uintptr_t)host;
zero_struct.range.len = getpagesize();
zero_struct.mode = 0;
if (ioctl(mis->userfault_fd, UFFDIO_ZEROPAGE, &zero_struct)) { if (ioctl(mis->userfault_fd, UFFDIO_ZEROPAGE, &zero_struct)) {
int e = errno; int e = errno;
error_report("%s: %s zero host: %p", error_report("%s: %s zero host: %p",
__func__, strerror(e), host); __func__, strerror(e), host);
return -e; return -e;
}
} else {
/* TODO: The kernel can't use UFFDIO_ZEROPAGE for hugepages */
assert(0);
} }
trace_postcopy_place_page_zero(host);
return 0; return 0;
} }
...@@ -604,7 +611,7 @@ int postcopy_place_page_zero(MigrationIncomingState *mis, void *host) ...@@ -604,7 +611,7 @@ int postcopy_place_page_zero(MigrationIncomingState *mis, void *host)
void *postcopy_get_tmp_page(MigrationIncomingState *mis) void *postcopy_get_tmp_page(MigrationIncomingState *mis)
{ {
if (!mis->postcopy_tmp_page) { if (!mis->postcopy_tmp_page) {
mis->postcopy_tmp_page = mmap(NULL, getpagesize(), mis->postcopy_tmp_page = mmap(NULL, mis->largest_page_size,
PROT_READ | PROT_WRITE, MAP_PRIVATE | PROT_READ | PROT_WRITE, MAP_PRIVATE |
MAP_ANONYMOUS, -1, 0); MAP_ANONYMOUS, -1, 0);
if (mis->postcopy_tmp_page == MAP_FAILED) { if (mis->postcopy_tmp_page == MAP_FAILED) {
...@@ -649,13 +656,15 @@ int postcopy_ram_enable_notify(MigrationIncomingState *mis) ...@@ -649,13 +656,15 @@ int postcopy_ram_enable_notify(MigrationIncomingState *mis)
return -1; return -1;
} }
int postcopy_place_page(MigrationIncomingState *mis, void *host, void *from) int postcopy_place_page(MigrationIncomingState *mis, void *host, void *from,
size_t pagesize)
{ {
assert(0); assert(0);
return -1; return -1;
} }
int postcopy_place_page_zero(MigrationIncomingState *mis, void *host) int postcopy_place_page_zero(MigrationIncomingState *mis, void *host,
size_t pagesize)
{ {
assert(0); assert(0);
return -1; return -1;
......
...@@ -2402,6 +2402,7 @@ static int ram_load_postcopy(QEMUFile *f) ...@@ -2402,6 +2402,7 @@ static int ram_load_postcopy(QEMUFile *f)
void *host = NULL; void *host = NULL;
void *page_buffer = NULL; void *page_buffer = NULL;
void *place_source = NULL; void *place_source = NULL;
RAMBlock *block = NULL;
uint8_t ch; uint8_t ch;
addr = qemu_get_be64(f); addr = qemu_get_be64(f);
...@@ -2411,7 +2412,7 @@ static int ram_load_postcopy(QEMUFile *f) ...@@ -2411,7 +2412,7 @@ static int ram_load_postcopy(QEMUFile *f)
trace_ram_load_postcopy_loop((uint64_t)addr, flags); trace_ram_load_postcopy_loop((uint64_t)addr, flags);
place_needed = false; place_needed = false;
if (flags & (RAM_SAVE_FLAG_COMPRESS | RAM_SAVE_FLAG_PAGE)) { if (flags & (RAM_SAVE_FLAG_COMPRESS | RAM_SAVE_FLAG_PAGE)) {
RAMBlock *block = ram_block_from_stream(f, flags); block = ram_block_from_stream(f, flags);
host = host_from_ram_block_offset(block, addr); host = host_from_ram_block_offset(block, addr);
if (!host) { if (!host) {
...@@ -2486,14 +2487,14 @@ static int ram_load_postcopy(QEMUFile *f) ...@@ -2486,14 +2487,14 @@ static int ram_load_postcopy(QEMUFile *f)
if (place_needed) { if (place_needed) {
/* This gets called at the last target page in the host page */ /* This gets called at the last target page in the host page */
void *place_dest = host + TARGET_PAGE_SIZE - block->page_size;
if (all_zero) { if (all_zero) {
ret = postcopy_place_page_zero(mis, ret = postcopy_place_page_zero(mis, place_dest,
host + TARGET_PAGE_SIZE - block->page_size);
qemu_host_page_size);
} else { } else {
ret = postcopy_place_page(mis, host + TARGET_PAGE_SIZE - ret = postcopy_place_page(mis, place_dest,
qemu_host_page_size, place_source, block->page_size);
place_source);
} }
} }
if (!ret) { if (!ret) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册