[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC 10/13] snapshot: Enable the write-protect notification
From: |
zhanghailiang |
Subject: |
[Qemu-devel] [RFC 10/13] snapshot: Enable the write-protect notification capability for VM's RAM |
Date: |
Thu, 7 Jan 2016 20:20:05 +0800 |
For live memory snapshot, we need to save the page before it is dirtied,
With the help of userfaultfd's write-protect notification capability,
we can get notification when the page is going to be dirtied, and save
the page before it is written.
We need to enable VM's ram write-protect notification capability with VM is
paused, and here we add UserfaultState parameter for struct MigrationState.
Signed-off-by: zhanghailiang <address@hidden>
---
include/migration/migration.h | 3 +++
include/migration/postcopy-ram.h | 3 +++
migration/migration.c | 6 +++++-
migration/postcopy-ram.c | 34 ++++++++++++++++++++++++++++++----
4 files changed, 41 insertions(+), 5 deletions(-)
diff --git a/include/migration/migration.h b/include/migration/migration.h
index 2312c73..ef4c071 100644
--- a/include/migration/migration.h
+++ b/include/migration/migration.h
@@ -173,6 +173,9 @@ struct MigrationState
QSIMPLEQ_HEAD(src_page_requests, MigrationSrcPageRequest)
src_page_requests;
/* The RAMBlock used in the last src_page_request */
RAMBlock *last_req_rb;
+
+ UserfaultState userfault_state;
+
bool in_snapshot; /* for snapshot */
};
diff --git a/include/migration/postcopy-ram.h b/include/migration/postcopy-ram.h
index 568cbdd..978a8d7 100644
--- a/include/migration/postcopy-ram.h
+++ b/include/migration/postcopy-ram.h
@@ -96,4 +96,7 @@ int postcopy_place_page_zero(MigrationIncomingState *mis,
void *host);
*/
void *postcopy_get_tmp_page(MigrationIncomingState *mis);
+int postcopy_ram_disable_notify(UserfaultState *us);
+
+void qemu_mlock_all_memory(void);
#endif
diff --git a/migration/migration.c b/migration/migration.c
index fd234eb..2001490 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -1751,6 +1751,8 @@ static void *snapshot_thread(void *opaque)
error_report("snapshot only support 'tcg' accel for now");
goto error;
}
+ /* userfaultfd's write-protected capability need all pages to be exist */
+ qemu_mlock_all_memory();
qemu_savevm_state_header(ms->file);
qemu_savevm_state_begin(ms->file, &ms->params);
@@ -1766,7 +1768,7 @@ static void *snapshot_thread(void *opaque)
goto error;
}
}
-
+ postcopy_ram_enable_notify(&ms->userfault_state, UFFDIO_REGISTER_MODE_WP);
buffer = qemu_save_device_buffer();
if (old_vm_running) {
@@ -1789,6 +1791,8 @@ static void *snapshot_thread(void *opaque)
MIGRATION_STATUS_COMPLETED);
}
+ postcopy_ram_disable_notify(&ms->userfault_state);
+
qemu_mutex_lock_iothread();
qemu_savevm_state_cleanup();
qemu_bh_schedule(ms->cleanup_bh);
diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c
index 370197e..9cd854b 100644
--- a/migration/postcopy-ram.c
+++ b/migration/postcopy-ram.c
@@ -279,7 +279,7 @@ int postcopy_ram_incoming_init(MigrationIncomingState *mis,
size_t ram_pages)
return 0;
}
-static int postcopy_ram_disable_notify(UserfaultState *us)
+int postcopy_ram_disable_notify(UserfaultState *us)
{
if (us->have_fault_thread) {
uint64_t tmp64;
@@ -370,9 +370,7 @@ static int nhp_range(const char *block_name, void
*host_addr,
*/
int postcopy_ram_prepare_discard(MigrationIncomingState *mis)
{
- if (qemu_ram_foreach_block(nhp_range, mis)) {
- return -1;
- }
+
postcopy_state_set(POSTCOPY_INCOMING_DISCARD);
@@ -586,6 +584,9 @@ int postcopy_ram_enable_notify(UserfaultState *us, int mode)
return -1;
}
+ if (qemu_ram_foreach_block(nhp_range, us)) {
+ return -1;
+ }
/*
* Ballooning can mark pages as absent while we're postcopying
* that would cause false userfaults.
@@ -816,3 +817,28 @@ void postcopy_discard_send_finish(MigrationState *ms,
PostcopyDiscardState *pds)
g_free(pds);
}
+
+static int ram_block_mlock(const char *block_name, void *host_addr,
+ ram_addr_t offset, ram_addr_t length,
+ void *opaque)
+{
+ int ret;
+
+ ret = mlock(host_addr, length);
+ if (ret < 0) {
+ error_report("%s mlock failed: %s", __func__, strerror(errno));
+ return -1;
+ }
+ return 0;
+}
+
+void qemu_mlock_all_memory(void)
+{
+ /* Users have configured mlock, so don't do it again */
+ if (enable_mlock) {
+ return;
+ }
+ if (qemu_ram_foreach_block(ram_block_mlock, NULL)) {
+ error_report("mlock all VM's memory failed");
+ }
+}
--
1.8.3.1
- [Qemu-devel] [RFC 00/13] Live memory snapshot based on userfaultfd, zhanghailiang, 2016/01/07
- [Qemu-devel] [RFC 10/13] snapshot: Enable the write-protect notification capability for VM's RAM,
zhanghailiang <=
- [Qemu-devel] [RFC 04/13] migration: Create a snapshot thread to realize saving memory snapshot, zhanghailiang, 2016/01/07
- [Qemu-devel] [RFC 05/13] migration: implement initialization work for snapshot, zhanghailiang, 2016/01/07
- [Qemu-devel] [RFC 11/13] snapshot/migration: Save VM's RAM into snapshot file, zhanghailiang, 2016/01/07
- [Qemu-devel] [RFC 13/13] snapshot: Remove page's write-protect and copy the content during setup stage, zhanghailiang, 2016/01/07
- [Qemu-devel] [RFC 03/13] migration: Allow -incoming to work on file: urls, zhanghailiang, 2016/01/07
- [Qemu-devel] [RFC 01/13] postcopy/migration: Split fault related state into struct UserfaultState, zhanghailiang, 2016/01/07
- [Qemu-devel] [RFC 09/13] migration/postcopy-ram: fix some helper functions to support userfaultfd write-protect, zhanghailiang, 2016/01/07
- [Qemu-devel] [RFC 02/13] migration: Allow the migrate command to work on file: urls, zhanghailiang, 2016/01/07