[CRIU] [PATCH v3 12/19] lazy-pages: extend the page_read with ability to read remote pages

Mike Rapoport rppt at linux.vnet.ibm.com
Tue Nov 15 08:57:21 PST 2016


Currently lazy-pages daemon uses either pr->read_pages or get_remote_pages
to get actual page data from local images or remote server. From now on,
page_read will be completely responsible for getting the page data.

Signed-off-by: Mike Rapoport <rppt at linux.vnet.ibm.com>
---
 criu/include/pagemap.h |  7 ++++++-
 criu/pagemap.c         | 32 +++++++++++++++++++++++++++-----
 criu/uffd.c            | 11 +++++------
 3 files changed, 38 insertions(+), 12 deletions(-)

diff --git a/criu/include/pagemap.h b/criu/include/pagemap.h
index 711e169..e4a4ecd 100644
--- a/criu/include/pagemap.h
+++ b/criu/include/pagemap.h
@@ -58,6 +58,9 @@ struct page_read {
 	void (*reset)(struct page_read *pr);
 	int (*sync)(struct page_read *pr);
 
+	int (*maybe_read_page)(struct page_read *pr, unsigned long vaddr,
+			       unsigned long len, void *buf, unsigned flags);
+
 	/* Private data of reader */
 	struct cr_img *pmi;
 	struct cr_img *pi;
@@ -72,7 +75,8 @@ struct page_read {
 
 	struct iovec bunch;		/* record consequent neighbour
 					   iovecs to punch together */
-	unsigned id; /* for logging */
+	unsigned id;			/* for logging */
+	int pid;			/* PID of the process */
 
 	PagemapEntry **pmes;
 	int nr_pmes;
@@ -90,6 +94,7 @@ struct page_read {
 
 #define PR_TYPE_MASK	0x3
 #define PR_MOD		0x4	/* Will need to modify */
+#define PR_REMOTE	0x8
 
 /*
  * -1 -- error
diff --git a/criu/pagemap.c b/criu/pagemap.c
index 1112515..728b031 100644
--- a/criu/pagemap.c
+++ b/criu/pagemap.c
@@ -10,6 +10,7 @@
 #include "cr_options.h"
 #include "servicefd.h"
 #include "pagemap.h"
+#include "page-xfer.h"
 
 #include "xmalloc.h"
 #include "protobuf.h"
@@ -377,8 +378,8 @@ static int enqueue_async_page(struct page_read *pr, unsigned long vaddr,
 	return 0;
 }
 
-static int maybe_read_page(struct page_read *pr, unsigned long vaddr,
-			   unsigned long len, void *buf, unsigned flags)
+static int maybe_read_page_local(struct page_read *pr, unsigned long vaddr,
+				 unsigned long len, void *buf, unsigned flags)
 {
 	int ret;
 
@@ -392,6 +393,19 @@ static int maybe_read_page(struct page_read *pr, unsigned long vaddr,
 	return ret;
 }
 
+static int maybe_read_page_remote(struct page_read *pr, unsigned long vaddr,
+				  unsigned long len, void *buf, unsigned flags)
+{
+	int ret;
+
+	if (flags & PR_ASYNC)
+		ret = -1;	/* not yet supported */
+	else
+		ret = get_remote_pages(pr->pid, vaddr, len / PAGE_SIZE, buf);
+
+	return ret;
+}
+
 static int read_pagemap_page(struct page_read *pr, unsigned long vaddr, int nr,
 			     void *buf, unsigned flags)
 {
@@ -407,7 +421,7 @@ static int read_pagemap_page(struct page_read *pr, unsigned long vaddr, int nr,
 		/* zero mappings should be skipped by get_pagemap */
 		BUG();
 	} else {
-		if (maybe_read_page(pr, vaddr, len, buf, flags) < 0)
+		if (pr->maybe_read_page(pr, vaddr, len, buf, flags) < 0)
 			return -1;
 	}
 
@@ -605,6 +619,7 @@ int open_page_read_at(int dfd, int pid, struct page_read *pr, int pr_flags)
 {
 	int flags, i_typ;
 	static unsigned ids = 1;
+	bool remote = pr_flags & PR_REMOTE;
 
 	if (opts.auto_dedup)
 		pr_flags |= PR_MOD;
@@ -668,9 +683,16 @@ int open_page_read_at(int dfd, int pid, struct page_read *pr, int pr_flags)
 	pr->reset = reset_pagemap;
 	pr->sync = process_async_reads;
 	pr->id = ids++;
+	pr->pid = pid;
+
+	if (remote)
+		pr->maybe_read_page = maybe_read_page_remote;
+	else
+		pr->maybe_read_page = maybe_read_page_local;
 
-	pr_debug("Opened page read %u (parent %u)\n",
-			pr->id, pr->parent ? pr->parent->id : 0);
+	pr_debug("Opened %s page read %u (parent %u)\n",
+		 remote ? "remote" : "local", pr->id,
+		 pr->parent ? pr->parent->id : 0);
 
 	return 1;
 }
diff --git a/criu/uffd.c b/criu/uffd.c
index e2c8016..2782531 100644
--- a/criu/uffd.c
+++ b/criu/uffd.c
@@ -452,6 +452,7 @@ static int ud_open(int client, struct lazy_pages_info **_lpi)
 	struct lazy_pages_info *lpi;
 	int ret = -1;
 	int uffd_flags;
+	int pr_flags = PR_TASK;
 
 	lpi = lpi_init();
 	if (!lpi)
@@ -485,7 +486,9 @@ static int ud_open(int client, struct lazy_pages_info **_lpi)
 	uffd_flags = fcntl(lpi->lpfd.fd, F_GETFD, NULL);
 	pr_debug("uffd_flags are 0x%x\n", uffd_flags);
 
-	ret = open_page_read(lpi->pid, &lpi->pr, PR_TASK);
+	if (opts.use_page_server)
+		pr_flags |= PR_REMOTE;
+	ret = open_page_read(lpi->pid, &lpi->pr, pr_flags);
 	if (ret <= 0) {
 		ret = -1;
 		goto out;
@@ -585,11 +588,7 @@ static int uffd_handle_pages(struct lazy_pages_info *lpi, __u64 address, int nr)
 	if (ret == 0 || pagemap_zero(lpi->pr.pe))
 		return uffd_zero(lpi, address, nr);
 
-	if (opts.use_page_server)
-		ret = get_remote_pages(lpi->pid, address, nr, lpi->buf);
-	else
-		ret = lpi->pr.read_pages(&lpi->pr, address, nr, lpi->buf, 0);
-
+	ret = lpi->pr.read_pages(&lpi->pr, address, nr, lpi->buf, 0);
 	if (ret <= 0) {
 		pr_err("%d: failed reading pages at %llx\n", lpi->pid, address);
 		return ret;
-- 
1.9.1



More information about the CRIU mailing list