[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v2 36/43] postcopy_ram.c: place_page and helpers
From: |
Dr. David Alan Gilbert (git) |
Subject: |
[Qemu-devel] [PATCH v2 36/43] postcopy_ram.c: place_page and helpers |
Date: |
Mon, 11 Aug 2014 15:29:52 +0100 |
From: "Dr. David Alan Gilbert" <address@hidden>
postcopy_place_page (etc) provide a way for postcopy to place a page
into guests memory atomically (using the new remap_anon_pages syscall).
Signed-off-by: Dr. David Alan Gilbert <address@hidden>
---
include/migration/migration.h | 1 +
include/migration/postcopy-ram.h | 23 +++++++++
postcopy-ram.c | 105 +++++++++++++++++++++++++++++++++++++++
3 files changed, 129 insertions(+)
diff --git a/include/migration/migration.h b/include/migration/migration.h
index 16f9db1..59d48bc 100644
--- a/include/migration/migration.h
+++ b/include/migration/migration.h
@@ -94,6 +94,7 @@ struct MigrationIncomingState {
QEMUFile *return_path;
QemuMutex rp_mutex; /* We send replies from multiple threads */
PostcopyPMI postcopy_pmi;
+ void *postcopy_tmp_page;
};
MigrationIncomingState *migration_incoming_get_current(void);
diff --git a/include/migration/postcopy-ram.h b/include/migration/postcopy-ram.h
index fc23558..eceea95 100644
--- a/include/migration/postcopy-ram.h
+++ b/include/migration/postcopy-ram.h
@@ -59,6 +59,29 @@ int postcopy_send_discard_bm_ram(MigrationState *ms, const
char *name,
void postcopy_hook_early_receive(MigrationIncomingState *mis,
size_t bitmap_index);
+/*
+ * Place a zero'd page of memory at *host
+ * returns 0 on success
+ */
+int postcopy_place_zero_page(MigrationIncomingState *mis, void *host,
+ long bitmap_offset);
+
+/*
+ * Place a page (from) at (host) efficiently
+ * There are restrictions on how 'from' must be mapped, in general best
+ * to use other postcopy_ routines to allocate.
+ * returns 0 on success
+ */
+int postcopy_place_page(MigrationIncomingState *mis, void *host, void *from,
+ long bitmap_offset);
+
+/*
+ * Allocate a page of memory that can be mapped at a later point in time
+ * using postcopy_place_page
+ * Returns: Pointer to allocated page
+ */
+void *postcopy_get_tmp_page(MigrationIncomingState *mis);
+
void postcopy_pmi_destroy(MigrationIncomingState *mis);
void postcopy_pmi_discard_range(MigrationIncomingState *mis,
size_t start, size_t npages);
diff --git a/postcopy-ram.c b/postcopy-ram.c
index 84b36d7..b37af47 100644
--- a/postcopy-ram.c
+++ b/postcopy-ram.c
@@ -349,6 +349,10 @@ int postcopy_ram_incoming_cleanup(MigrationIncomingState
*mis)
return -1;
}
+ if (mis->postcopy_tmp_page) {
+ munmap(mis->postcopy_tmp_page, getpagesize());
+ mis->postcopy_tmp_page = NULL;
+ }
return 0;
}
@@ -405,6 +409,88 @@ int postcopy_ram_enable_notify(MigrationIncomingState *mis)
return 0;
}
+/*
+ * Place a zero'd page of memory at *host
+ * returns 0 on success
+ * bitmap_offset: Index into the migration bitmaps
+ */
+int postcopy_place_zero_page(MigrationIncomingState *mis, void *host,
+ long bitmap_offset)
+{
+ void *tmp = postcopy_get_tmp_page(mis);
+ if (!tmp) {
+ return -ENOMEM;
+ }
+ *(char *)tmp = 0;
+ return postcopy_place_page(mis, host, tmp, bitmap_offset);
+}
+
+/*
+ * Place a page (from) at (host) efficiently
+ * There are restrictions on how 'from' must be mapped, in general best
+ * to use other postcopy_ routines to allocate.
+ * returns 0 on success
+ * bitmap_offset: Index into the migration bitmaps
+ */
+int postcopy_place_page(MigrationIncomingState *mis, void *host, void *from,
+ long bitmap_offset)
+{
+ PostcopyPMIState old_state, tmp_state;
+
+ if (syscall(__NR_remap_anon_pages, host, from, getpagesize(), 0) !=
+ getpagesize()) {
+ perror("remap_anon_pages in postcopy_place_page");
+ fprintf(stderr, "host: %p from: %p pmi=%d\n", host, from,
+ postcopy_pmi_get_state(mis, bitmap_offset));
+
+ return -errno;
+ }
+
+ tmp_state = postcopy_pmi_get_state(mis, bitmap_offset);
+ do {
+ old_state = tmp_state;
+ tmp_state = postcopy_pmi_change_state(mis, bitmap_offset, old_state,
+ POSTCOPY_PMI_RECEIVED);
+
+ } while (old_state != tmp_state);
+
+
+ if (old_state == POSTCOPY_PMI_REQUESTED) {
+ /* TODO: Notify kernel */
+ }
+
+ /* TODO: hostpagesize!=targetpagesize case */
+ return 0;
+}
+
+/*
+ * Returns a page of memory that can be mapped at a later point in time
+ * using postcopy_place_page
+ * The same address is used repeatedly, postcopy_place_page just takes the
+ * backing page away.
+ * Returns: Pointer to allocated page
+ */
+void *postcopy_get_tmp_page(MigrationIncomingState *mis)
+{
+
+ if (!mis->postcopy_tmp_page) {
+ mis->postcopy_tmp_page = mmap(NULL, getpagesize(),
+ PROT_READ | PROT_WRITE, MAP_PRIVATE |
+ MAP_ANONYMOUS, -1, 0);
+ if (!mis->postcopy_tmp_page) {
+ perror("mapping postcopy tmp page");
+ return NULL;
+ }
+ if (madvise(mis->postcopy_tmp_page, getpagesize(), MADV_DONTFORK)) {
+ munmap(mis->postcopy_tmp_page, getpagesize());
+ perror("postcpy tmp page DONTFORK");
+ return NULL;
+ }
+ }
+
+ return mis->postcopy_tmp_page;
+}
+
#else
/* No target OS support, stubs just fail */
int postcopy_ram_hosttest(void)
@@ -444,6 +530,25 @@ int postcopy_ram_enable_notify(MigrationIncomingState *mis)
fprintf(stderr, "postcopy_ram_enable_notify: No OS support\n");
return -1;
}
+
+int postcopy_place_zero_page(MigrationIncomingState *mis, void *host)
+{
+ error_report("postcopy_place_zero_page: No OS support");
+ return -1;
+}
+
+int postcopy_place_page(MigrationIncomingState *mis, void *host, void *from)
+{
+ error_report("postcopy_place_page: No OS support");
+ return -1;
+}
+
+void *postcopy_get_tmp_page(MigrationIncomingState *mis)
+{
+ error_report("postcopy_get_tmp_page: No OS support");
+ return -1;
+}
+
#endif
/* ------------------------------------------------------------------------- */
--
1.9.3
- [Qemu-devel] [PATCH v2 25/43] postcopy: Add incoming_init/cleanup functions, (continued)
- [Qemu-devel] [PATCH v2 25/43] postcopy: Add incoming_init/cleanup functions, Dr. David Alan Gilbert (git), 2014/08/11
- [Qemu-devel] [PATCH v2 23/43] Postcopy: Maintain sentmap during postcopy pre phase, Dr. David Alan Gilbert (git), 2014/08/11
- [Qemu-devel] [PATCH v2 27/43] postcopy: ram_enable_notify to switch on userfault, Dr. David Alan Gilbert (git), 2014/08/11
- [Qemu-devel] [PATCH v2 26/43] postcopy: Incoming initialisation, Dr. David Alan Gilbert (git), 2014/08/11
- [Qemu-devel] [PATCH v2 28/43] Postcopy: postcopy_start, Dr. David Alan Gilbert (git), 2014/08/11
- [Qemu-devel] [PATCH v2 29/43] Postcopy: Rework migration thread for postcopy mode, Dr. David Alan Gilbert (git), 2014/08/11
- [Qemu-devel] [PATCH v2 30/43] mig fd_connect: open return path, Dr. David Alan Gilbert (git), 2014/08/11
- [Qemu-devel] [PATCH v2 31/43] Postcopy: Create a fault handler thread before marking the ram as userfault, Dr. David Alan Gilbert (git), 2014/08/11
- [Qemu-devel] [PATCH v2 33/43] Page request: Process incoming page request, Dr. David Alan Gilbert (git), 2014/08/11
- [Qemu-devel] [PATCH v2 34/43] Page request: Consume pages off the post-copy queue, Dr. David Alan Gilbert (git), 2014/08/11
- [Qemu-devel] [PATCH v2 36/43] postcopy_ram.c: place_page and helpers,
Dr. David Alan Gilbert (git) <=
- [Qemu-devel] [PATCH v2 35/43] Add assertion to check migration_dirty_pages, Dr. David Alan Gilbert (git), 2014/08/11
- [Qemu-devel] [PATCH v2 38/43] qemu_ram_block_from_host, Dr. David Alan Gilbert (git), 2014/08/11
- [Qemu-devel] [PATCH v2 37/43] Postcopy: Use helpers to map pages during migration, Dr. David Alan Gilbert (git), 2014/08/11
- [Qemu-devel] [PATCH v2 40/43] Start up a postcopy/listener thread ready for incoming page data, Dr. David Alan Gilbert (git), 2014/08/11
- [Qemu-devel] [PATCH v2 41/43] postcopy: Wire up loadvm_postcopy_ram_handle_{run, end} commands, Dr. David Alan Gilbert (git), 2014/08/11
- [Qemu-devel] [PATCH v2 39/43] Postcopy; Handle userfault requests, Dr. David Alan Gilbert (git), 2014/08/11
- [Qemu-devel] [PATCH v2 42/43] End of migration for postcopy, Dr. David Alan Gilbert (git), 2014/08/11
- [Qemu-devel] [PATCH v2 43/43] Start documenting how postcopy works., Dr. David Alan Gilbert (git), 2014/08/11