[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v4 32/47] postcopy: ram_enable_notify to switch on u
From: |
Dr. David Alan Gilbert (git) |
Subject: |
[Qemu-devel] [PATCH v4 32/47] postcopy: ram_enable_notify to switch on userfault |
Date: |
Fri, 3 Oct 2014 18:47:38 +0100 |
From: "Dr. David Alan Gilbert" <address@hidden>
Signed-off-by: Dr. David Alan Gilbert <address@hidden>
---
include/migration/migration.h | 2 ++
include/migration/postcopy-ram.h | 6 +++++
postcopy-ram.c | 49 +++++++++++++++++++++++++++++++++++++++-
savevm.c | 9 ++++++++
4 files changed, 65 insertions(+), 1 deletion(-)
diff --git a/include/migration/migration.h b/include/migration/migration.h
index be63c89..b01cc17 100644
--- a/include/migration/migration.h
+++ b/include/migration/migration.h
@@ -87,6 +87,8 @@ struct MigrationIncomingState {
POSTCOPY_RAM_INCOMING_END
} postcopy_ram_state;
+ /* For the kernel to send us notifications */
+ int userfault_fd;
QEMUFile *return_path;
QemuMutex rp_mutex; /* We send replies from multiple threads */
PostcopyPMI postcopy_pmi;
diff --git a/include/migration/postcopy-ram.h b/include/migration/postcopy-ram.h
index 8f237a2..413b670 100644
--- a/include/migration/postcopy-ram.h
+++ b/include/migration/postcopy-ram.h
@@ -19,6 +19,12 @@
int postcopy_ram_hosttest(void);
/*
+ * Make all of RAM sensitive to accesses to areas that haven't yet been written
+ * and wire up anything necessary to deal with it.
+ */
+int postcopy_ram_enable_notify(MigrationIncomingState *mis);
+
+/*
* Initialise postcopy-ram, setting the RAM to a state where we can go into
* postcopy later; must be called prior to any precopy.
* called from arch_init's similarly named ram_postcopy_incoming_init
diff --git a/postcopy-ram.c b/postcopy-ram.c
index 8eccf26..925ac77 100644
--- a/postcopy-ram.c
+++ b/postcopy-ram.c
@@ -485,9 +485,51 @@ int postcopy_ram_incoming_cleanup(MigrationIncomingState
*mis)
return 0;
}
+/*
+ * Mark the given area of RAM as requiring notification to unwritten areas
+ * Used as a callback on qemu_ram_foreach_block.
+ * host_addr: Base of area to mark
+ * offset: Offset in the whole ram arena
+ * length: Length of the section
+ * opaque: Unused
+ * Returns 0 on success
+ */
+static int postcopy_ram_sensitise_area(const char *block_name, void *host_addr,
+ ram_addr_t offset, ram_addr_t length,
+ void *opaque)
+{
+ MigrationIncomingState *mis = opaque;
+ uint64_t tokern[2];
+
+ if (madvise(host_addr, length, MADV_USERFAULT)) {
+ perror("postcopy_ram_sensitise_area madvise");
+ return -1;
+ }
+
+ /* Now tell our userfault_fd that it's responsible for this area */
+ tokern[0] = (uint64_t)(uintptr_t)host_addr | 1; /* 1 means register area */
+ tokern[1] = (uint64_t)(uintptr_t)host_addr + length;
+ if (write(mis->userfault_fd, tokern, 16) != 16) {
+ perror("postcopy_ram_sensitise_area write");
+ madvise(host_addr, length, MADV_NOUSERFAULT);
+ return -1;
+ }
+
+ return 0;
+}
+
+int postcopy_ram_enable_notify(MigrationIncomingState *mis)
+{
+ /* Mark so that we get notified of accesses to unwritten areas */
+ if (qemu_ram_foreach_block(postcopy_ram_sensitise_area, mis)) {
+ return -1;
+ }
+
+ return 0;
+}
+
#else
/* No target OS support, stubs just fail */
-
int postcopy_ram_hosttest(void)
{
error_report("postcopy_ram_hosttest: No OS support");
@@ -528,6 +570,11 @@ int postcopy_ram_discard_range(MigrationIncomingState
*mis, uint8_t *start,
{
assert(0);
}
+
+int postcopy_ram_enable_notify(MigrationIncomingState *mis)
+{
+ assert(0);
+}
#endif
/* ------------------------------------------------------------------------- */
diff --git a/savevm.c b/savevm.c
index 54bdb26..859c96f 100644
--- a/savevm.c
+++ b/savevm.c
@@ -1304,6 +1304,15 @@ static int
loadvm_postcopy_ram_handle_listen(MigrationIncomingState *mis)
mis->postcopy_ram_state = POSTCOPY_RAM_INCOMING_LISTENING;
+ /*
+ * Sensitise RAM - can now generate requests for blocks that don't exist
+ * However, at this point the CPU shouldn't be running, and the IO
+ * shouldn't be doing anything yet so don't actually expect requests
+ */
+ if (postcopy_ram_enable_notify(mis)) {
+ return -1;
+ }
+
/* TODO start up the postcopy listening thread */
return 0;
}
--
1.9.3
- [Qemu-devel] [PATCH v4 23/47] migrate_init: Call from savevm, (continued)
- [Qemu-devel] [PATCH v4 23/47] migrate_init: Call from savevm, Dr. David Alan Gilbert (git), 2014/10/03
- [Qemu-devel] [PATCH v4 24/47] Allow savevm handlers to state whether they could go into postcopy, Dr. David Alan Gilbert (git), 2014/10/03
- [Qemu-devel] [PATCH v4 25/47] postcopy: OS support test, Dr. David Alan Gilbert (git), 2014/10/03
- [Qemu-devel] [PATCH v4 26/47] migrate_start_postcopy: Command to trigger transition to postcopy, Dr. David Alan Gilbert (git), 2014/10/03
- [Qemu-devel] [PATCH v4 27/47] MIG_STATE_POSTCOPY_ACTIVE: Add new migration state, Dr. David Alan Gilbert (git), 2014/10/03
- [Qemu-devel] [PATCH v4 28/47] qemu_savevm_state_complete: Postcopy changes, Dr. David Alan Gilbert (git), 2014/10/03
- [Qemu-devel] [PATCH v4 29/47] Postcopy page-map-incoming (PMI) structure, Dr. David Alan Gilbert (git), 2014/10/03
- [Qemu-devel] [PATCH v4 30/47] Postcopy: Maintain sentmap and calculate discard, Dr. David Alan Gilbert (git), 2014/10/03
- [Qemu-devel] [PATCH v4 31/47] postcopy: Incoming initialisation, Dr. David Alan Gilbert (git), 2014/10/03
- [Qemu-devel] [PATCH v4 32/47] postcopy: ram_enable_notify to switch on userfault,
Dr. David Alan Gilbert (git) <=
- [Qemu-devel] [PATCH v4 33/47] Postcopy: Postcopy startup in migration thread, Dr. David Alan Gilbert (git), 2014/10/03
- [Qemu-devel] [PATCH v4 35/47] Page request: Add MIG_RPCOMM_REQPAGES reverse command, Dr. David Alan Gilbert (git), 2014/10/03
- [Qemu-devel] [PATCH v4 36/47] Page request: Process incoming page request, Dr. David Alan Gilbert (git), 2014/10/03