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>
This commit is contained in:
parent
df9ff5e1e3
commit
41d84210d4
@ -109,6 +109,7 @@ struct MigrationIncomingState {
|
|||||||
QEMUFile *to_src_file;
|
QEMUFile *to_src_file;
|
||||||
QemuMutex rp_mutex; /* We send replies from multiple threads */
|
QemuMutex rp_mutex; /* We send replies from multiple threads */
|
||||||
void *postcopy_tmp_page;
|
void *postcopy_tmp_page;
|
||||||
|
void *postcopy_tmp_zero_page;
|
||||||
|
|
||||||
QEMUBH *bh;
|
QEMUBH *bh;
|
||||||
|
|
||||||
|
@ -324,6 +324,10 @@ int postcopy_ram_incoming_cleanup(MigrationIncomingState *mis)
|
|||||||
munmap(mis->postcopy_tmp_page, mis->largest_page_size);
|
munmap(mis->postcopy_tmp_page, mis->largest_page_size);
|
||||||
mis->postcopy_tmp_page = NULL;
|
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();
|
trace_postcopy_ram_incoming_cleanup_exit();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -593,8 +597,23 @@ int postcopy_place_page_zero(MigrationIncomingState *mis, void *host,
|
|||||||
return -e;
|
return -e;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* TODO: The kernel can't use UFFDIO_ZEROPAGE for hugepages */
|
/* The kernel can't use UFFDIO_ZEROPAGE for hugepages */
|
||||||
assert(0);
|
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;
|
return 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user