[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 38/46] postcopy_ram.c: place_page and helpers
From: |
Dr. David Alan Gilbert (git) |
Subject: |
[Qemu-devel] [PATCH 38/46] postcopy_ram.c: place_page and helpers |
Date: |
Fri, 4 Jul 2014 18:41:49 +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 fe639b4..1a33b05 100644
--- a/include/migration/migration.h
+++ b/include/migration/migration.h
@@ -93,6 +93,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_state_init(QEMUFile *f);
diff --git a/include/migration/postcopy-ram.h b/include/migration/postcopy-ram.h
index 383b1e8..57a74f0 100644
--- a/include/migration/postcopy-ram.h
+++ b/include/migration/postcopy-ram.h
@@ -53,6 +53,29 @@ int postcopy_ram_incoming_cleanup(MigrationIncomingState
*mis);
int postcopy_send_discard_bm_ram(MigrationState *ms, const char *name,
unsigned long start, unsigned long end);
+/*
+ * 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 fb7b02b..de3534f 100644
--- a/postcopy-ram.c
+++ b/postcopy-ram.c
@@ -334,6 +334,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;
}
@@ -390,6 +394,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)
@@ -422,6 +508,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 28/46] postcopy: Incoming initialisation, (continued)
- [Qemu-devel] [PATCH 28/46] postcopy: Incoming initialisation, Dr. David Alan Gilbert (git), 2014/07/04
- [Qemu-devel] [PATCH 30/46] Postcopy: postcopy_start, Dr. David Alan Gilbert (git), 2014/07/04
- [Qemu-devel] [PATCH 32/46] mig fd_connect: open return path, Dr. David Alan Gilbert (git), 2014/07/04
- [Qemu-devel] [PATCH 31/46] Postcopy: Rework migration thread for postcopy mode, Dr. David Alan Gilbert (git), 2014/07/04
- [Qemu-devel] [PATCH 33/46] Postcopy: Create a fault handler thread before marking the ram as userfault, Dr. David Alan Gilbert (git), 2014/07/04
- [Qemu-devel] [PATCH 34/46] Page request: Add MIG_RPCOMM_REQPAGES reverse command, Dr. David Alan Gilbert (git), 2014/07/04
- [Qemu-devel] [PATCH 36/46] Page request: Consume pages off the post-copy queue, Dr. David Alan Gilbert (git), 2014/07/04
- [Qemu-devel] [PATCH 37/46] Add assertion to check migration_dirty_pages doesn't go -ve; have seen it happen once but not sure why, Dr. David Alan Gilbert (git), 2014/07/04
- [Qemu-devel] [PATCH 35/46] Page request: Process incoming page request, Dr. David Alan Gilbert (git), 2014/07/04
- [Qemu-devel] [PATCH 38/46] postcopy_ram.c: place_page and helpers,
Dr. David Alan Gilbert (git) <=
- [Qemu-devel] [PATCH 39/46] Postcopy: Use helpers to map pages during migration, Dr. David Alan Gilbert (git), 2014/07/04
- [Qemu-devel] [PATCH 43/46] postcopy: Wire up loadvm_postcopy_ram_handle_{run, end} commands, Dr. David Alan Gilbert (git), 2014/07/04
- [Qemu-devel] [PATCH 44/46] postcopy: Use userfaultfd, Dr. David Alan Gilbert (git), 2014/07/04
- [Qemu-devel] [PATCH 45/46] End of migration for postcopy, Dr. David Alan Gilbert (git), 2014/07/04
- [Qemu-devel] [PATCH 46/46] Start documenting how postcopy works., Dr. David Alan Gilbert (git), 2014/07/04
- [Qemu-devel] [PATCH 16/46] Add migration-capability boolean for postcopy-ram., Dr. David Alan Gilbert (git), 2014/07/04