[CRIU] [RFC PATCH 4/7] page-xfer: add methods for requesting and receiving remote pages
Mike Rapoport
rppt at linux.vnet.ibm.com
Mon Nov 14 07:37:27 PST 2016
For asynchrounous page transfers in post-copy migration we need to be able
to request a remote pages, receive back information about the data is going
to arrive and receive the page data itself.
Signed-off-by: Mike Rapoport <rppt at linux.vnet.ibm.com>
---
criu/include/page-xfer.h | 17 +++++++++++++++++
criu/page-xfer.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 62 insertions(+)
diff --git a/criu/include/page-xfer.h b/criu/include/page-xfer.h
index fdda105..7cd0055 100644
--- a/criu/include/page-xfer.h
+++ b/criu/include/page-xfer.h
@@ -42,6 +42,23 @@ extern int disconnect_from_page_server(void);
extern int check_parent_page_xfer(int fd_type, long id);
+/*
+ * The post-copy migration makes it necessary to receive pages from
+ * remote dump. The protocol we use for that is quite simple:
+ * - lazy-pages sedns request containing PS_IOV_GET(nr_pages, vaddr, pid)
+ * - dump-side page server responds with PS_IOV_ADD(nr_pages, vaddr,
+ pid) or PS_IOV_ADD(0, 0, 0) if it failed to locate the required
+ pages
+ * - dump-side page server sends the raw page data
+ */
+
+/* sync receive of remote pages */
extern int get_remote_pages(int pid, unsigned long addr, int nr_pages, void *dest);
+/* async request/receive of remote pages */
+extern int request_remote_pages(int pid, unsigned long addr, int nr_pages);
+extern int receive_remote_pages_info(int *nr_pages, unsigned long *addr, int *pid);
+extern int receive_remote_pages(int len, void *buf);
+
+
#endif /* __CR_PAGE_XFER__H__ */
diff --git a/criu/page-xfer.c b/criu/page-xfer.c
index b509136..6956f2b 100644
--- a/criu/page-xfer.c
+++ b/criu/page-xfer.c
@@ -916,3 +916,48 @@ int get_remote_pages(int pid, unsigned long addr, int nr_pages, void *dest)
return 1;
}
+
+int request_remote_pages(int pid, unsigned long addr, int nr_pages)
+{
+ struct page_server_iov pi = {
+ .cmd = PS_IOV_GET,
+ .nr_pages = nr_pages,
+ .vaddr = addr,
+ .dst_id = pid,
+ };
+
+ /* We cannot use send_psi here because we have to use MSG_DONTWAIT */
+ if (send(page_server_sk, &pi, sizeof(pi), MSG_DONTWAIT) != sizeof(pi)) {
+ pr_perror("Can't write PSI to server");
+ return -1;
+ }
+
+ tcp_nodelay(page_server_sk, true);
+ return 0;
+}
+
+int receive_remote_pages_info(int *nr_pages, unsigned long *addr, int *pid)
+{
+ struct page_server_iov pi;
+
+ if (recv(page_server_sk, &pi, sizeof(pi), MSG_WAITALL) != sizeof(pi)) {
+ pr_perror("Failed to receive page metadata");
+ return -1;
+ }
+
+ *nr_pages = pi.nr_pages;
+ *addr = pi.vaddr;
+ *pid = pi.dst_id;
+
+ return 0;
+}
+
+int receive_remote_pages(int len, void *buf)
+{
+ if (recv(page_server_sk, buf, len, MSG_WAITALL) != len) {
+ pr_perror("Failed to receive page data");
+ return -1;
+ }
+
+ return 0;
+}
--
1.9.1
More information about the CRIU
mailing list