qemu-devel
[Top][All Lists]
Advanced

[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





reply via email to

[Prev in Thread] Current Thread [Next in Thread]