[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v4 25/47] postcopy: OS support test
From: |
Dr. David Alan Gilbert (git) |
Subject: |
[Qemu-devel] [PATCH v4 25/47] postcopy: OS support test |
Date: |
Fri, 3 Oct 2014 18:47:31 +0100 |
From: "Dr. David Alan Gilbert" <address@hidden>
Provide a check to see if the OS we're running on has all the bits
needed for postcopy.
Creates postcopy-ram.c which will get most of the other helpers we need.
Signed-off-by: Dr. David Alan Gilbert <address@hidden>
---
Makefile.objs | 2 +-
include/migration/postcopy-ram.h | 19 +++++
postcopy-ram.c | 160 +++++++++++++++++++++++++++++++++++++++
savevm.c | 6 ++
4 files changed, 186 insertions(+), 1 deletion(-)
create mode 100644 include/migration/postcopy-ram.h
create mode 100644 postcopy-ram.c
diff --git a/Makefile.objs b/Makefile.objs
index 97db978..fa0a3a0 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -54,7 +54,7 @@ common-obj-y += qemu-file.o
common-obj-$(CONFIG_RDMA) += migration-rdma.o
common-obj-y += qemu-char.o #aio.o
common-obj-y += block-migration.o
-common-obj-y += page_cache.o xbzrle.o
+common-obj-y += page_cache.o xbzrle.o postcopy-ram.o
common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration-fd.o
diff --git a/include/migration/postcopy-ram.h b/include/migration/postcopy-ram.h
new file mode 100644
index 0000000..dcd1afa
--- /dev/null
+++ b/include/migration/postcopy-ram.h
@@ -0,0 +1,19 @@
+/*
+ * Postcopy migration for RAM
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates
+ *
+ * Authors:
+ * Dave Gilbert <address@hidden>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+#ifndef QEMU_POSTCOPY_RAM_H
+#define QEMU_POSTCOPY_RAM_H
+
+/* Return 0 if the host supports everything we need to do postcopy-ram */
+int postcopy_ram_hosttest(void);
+
+#endif
diff --git a/postcopy-ram.c b/postcopy-ram.c
new file mode 100644
index 0000000..bba5c71
--- /dev/null
+++ b/postcopy-ram.c
@@ -0,0 +1,160 @@
+/*
+ * Postcopy migration for RAM
+ *
+ * Copyright 2013-2014 Red Hat, Inc. and/or its affiliates
+ *
+ * Authors:
+ * Dave Gilbert <address@hidden>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+/*
+ * Postcopy is a migration technique where the execution flips from the
+ * source to the destination before all the data has been copied.
+ */
+
+#include <glib.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "qemu-common.h"
+#include "migration/migration.h"
+#include "migration/postcopy-ram.h"
+
+//#define DEBUG_POSTCOPY
+
+#ifdef DEBUG_POSTCOPY
+#define DPRINTF(fmt, ...) \
+ do { fprintf(stderr, "address@hidden" PRId64 " " fmt "\n", \
+ qemu_clock_get_ms(QEMU_CLOCK_REALTIME), \
+ ## __VA_ARGS__); } while (0)
+#else
+#define DPRINTF(fmt, ...) \
+ do { } while (0)
+#endif
+
+/* Postcopy needs to detect accesses to pages that haven't yet been copied
+ * across, and efficiently map new pages in, the techniques for doing this
+ * are target OS specific.
+ */
+#if defined(__linux__)
+
+/* On Linux we use:
+ * madvise MADV_USERFAULT - to mark an area of anonymous memory such
+ * that userspace is notifed of accesses to
+ * unallocated areas.
+ * userfaultfd - opens a socket to receive USERFAULT messages
+ * remap_anon_pages - to shuffle mapped pages into previously unallocated
+ * areas without creating loads of VMAs.
+ */
+
+#include <sys/mman.h>
+#include <sys/types.h>
+
+/* TODO remove once we have libc defs */
+
+#ifdef HOST_X86_64
+ /* NOTE: These are Andrea's 3.15.0 world */
+#ifndef MADV_USERFAULT
+#define MADV_USERFAULT 18
+#define MADV_NOUSERFAULT 19
+#endif
+
+#ifndef __NR_remap_anon_pages
+#define __NR_remap_anon_pages 321
+#endif
+
+#ifndef __NR_userfaultfd
+#define __NR_userfaultfd 322
+#endif
+
+#endif
+
+#ifndef USERFAULTFD_PROTOCOL
+#define USERFAULTFD_PROTOCOL (uint64_t)0xaa
+#endif
+
+#endif
+
+#if defined(__linux__) && defined(MADV_USERFAULT) && \
+ defined(__NR_remap_anon_pages)
+
+int postcopy_ram_hosttest(void)
+{
+ /* TODO: Needs guarding with CONFIG_ once we have libc's that have the defs
+ *
+ * Try each syscall we need, but this isn't a testbench,
+ * just enough to see that we have the calls
+ */
+ void *testarea = NULL, *testarea2 = NULL;
+ long pagesize = getpagesize();
+ int ufd = -1;
+ int ret = -1; /* Error unless we change it */
+
+ testarea = mmap(NULL, pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE |
+ MAP_ANONYMOUS, -1, 0);
+ if (!testarea) {
+ perror("postcopy_ram_hosttest: Failed to map test area");
+ goto out;
+ }
+ g_assert(((size_t)testarea & (pagesize-1)) == 0);
+
+ ufd = syscall(__NR_userfaultfd, O_CLOEXEC);
+ if (ufd == -1) {
+ perror("postcopy_ram_hosttest: userfaultfd not available");
+ goto out;
+ }
+
+ if (madvise(testarea, pagesize, MADV_USERFAULT)) {
+ perror("postcopy_ram_hosttest: MADV_USERFAULT not available");
+ goto out;
+ }
+
+ if (madvise(testarea, pagesize, MADV_NOUSERFAULT)) {
+ perror("postcopy_ram_hosttest: MADV_NOUSERFAULT not available");
+ goto out;
+ }
+
+ testarea2 = mmap(NULL, pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE |
+ MAP_ANONYMOUS, -1, 0);
+ if (!testarea2) {
+ perror("postcopy_ram_hosttest: Failed to map second test area");
+ goto out;
+ }
+ g_assert(((size_t)testarea2 & (pagesize-1)) == 0);
+ *(char *)testarea = 0; /* Force the map of the new page */
+ if (syscall(__NR_remap_anon_pages, testarea2, testarea, pagesize, 0) !=
+ pagesize) {
+ perror("postcopy_ram_hosttest: remap_anon_pages not available");
+ goto out;
+ }
+
+ /* Success! */
+ ret = 0;
+out:
+ if (testarea) {
+ munmap(testarea, pagesize);
+ }
+ if (testarea2) {
+ munmap(testarea2, pagesize);
+ }
+ if (ufd != -1) {
+ close(ufd);
+ }
+ return ret;
+}
+
+#else
+/* No target OS support, stubs just fail */
+
+int postcopy_ram_hosttest(void)
+{
+ error_report("postcopy_ram_hosttest: No OS support");
+ return -1;
+}
+
+#endif
+
diff --git a/savevm.c b/savevm.c
index 1642a59..a0cb88b 100644
--- a/savevm.c
+++ b/savevm.c
@@ -33,6 +33,7 @@
#include "qemu/timer.h"
#include "audio/audio.h"
#include "migration/migration.h"
+#include "migration/postcopy-ram.h"
#include "qemu/sockets.h"
#include "qemu/queue.h"
#include "sysemu/cpus.h"
@@ -1087,6 +1088,11 @@ static int
loadvm_postcopy_ram_handle_advise(MigrationIncomingState *mis,
return -1;
}
+ /* Check this host can do it */
+ if (postcopy_ram_hosttest()) {
+ return -1;
+ }
+
if (remote_hps != sysconf(_SC_PAGESIZE)) {
/*
* Some combinations of mismatch are probably possible but it gets
--
1.9.3
- Re: [Qemu-devel] [PATCH v4 19/47] Rework loadvm path for subloops, (continued)
[Qemu-devel] [PATCH v4 20/47] Add migration-capability boolean for postcopy-ram., Dr. David Alan Gilbert (git), 2014/10/03
[Qemu-devel] [PATCH v4 21/47] Add wrappers and handlers for sending/receiving the postcopy-ram migration messages., Dr. David Alan Gilbert (git), 2014/10/03
[Qemu-devel] [PATCH v4 22/47] QEMU_VM_CMD_PACKAGED: Send a packaged chunk of migration stream, Dr. David Alan Gilbert (git), 2014/10/03
[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) <=
[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), 2014/10/03
[Qemu-devel] [PATCH v4 33/47] Postcopy: Postcopy startup in migration thread, Dr. David Alan Gilbert (git), 2014/10/03