[CRIU] [PATCH] lazy-pages: use intermediate pipe in page_server_get_pages

Mike Rapoport rppt at linux.vnet.ibm.com
Mon Jun 5 17:52:26 MSK 2017


Instead of splice()'ing pages directly from the page-pipe into the socket,
use intermediate pipe and tee(). This way we keep the pages in page-pipe
and they can be fetched again by the processes that were fork()'ed after
restore.

Signed-off-by: Mike Rapoport <rppt at linux.vnet.ibm.com>
---
 criu/page-xfer.c | 28 ++++++++++++++++------------
 1 file changed, 16 insertions(+), 12 deletions(-)

diff --git a/criu/page-xfer.c b/criu/page-xfer.c
index c557407..6217d8a 100644
--- a/criu/page-xfer.c
+++ b/criu/page-xfer.c
@@ -705,17 +705,19 @@ static int page_server_get_pages(int sk, struct page_server_iov *pi)
 	if (!can_send_pages(ppb, iov, pi))
 		return -1;
 
+	ret = tee(ppb->p[0], cxfer.p[1], iov->iov_len, 0);
+	if (ret != iov->iov_len)
+		return -1;
+
 	if (send_psi(sk, PS_IOV_ADD, pi->nr_pages, pi->vaddr, pi->dst_id))
 		return -1;
 
-	ret = splice(ppb->p[0], NULL, sk, NULL, iov->iov_len, SPLICE_F_MOVE);
+	ret = splice(cxfer.p[0], NULL, sk, NULL, iov->iov_len, SPLICE_F_MOVE);
 	if (ret != iov->iov_len)
 		return -1;
 
 	tcp_nodelay(sk, true);
 
-	page_pipe_destroy_ppb(ppb);
-
 	return 0;
 }
 
@@ -724,6 +726,12 @@ static int page_server_serve(int sk)
 	int ret = -1;
 	bool flushed = false;
 
+	if (pipe(cxfer.p)) {
+		pr_perror("Can't make pipe for xfer");
+		close(sk);
+		return -1;
+	}
+
 	if (!opts.lazy_pages) {
 		/*
 		 * This socket only accepts data except one thing -- it
@@ -731,19 +739,15 @@ static int page_server_serve(int sk)
 		 * make it NODELAY all the time.
 		 */
 		tcp_nodelay(sk, true);
-
-		if (pipe(cxfer.p)) {
-			pr_perror("Can't make pipe for xfer");
-			close(sk);
-			return -1;
-		}
-
-		cxfer.pipe_size = fcntl(cxfer.p[0], F_GETPIPE_SZ, 0);
-		pr_debug("Created xfer pipe size %u\n", cxfer.pipe_size);
 	} else {
+		if (fcntl(cxfer.p[0], F_SETPIPE_SZ, PIPE_MAX_SIZE * PAGE_SIZE) < 0)
+			return -1;
 		tcp_cork(sk, true);
 	}
 
+	cxfer.pipe_size = fcntl(cxfer.p[0], F_GETPIPE_SZ, 0);
+	pr_debug("Created xfer pipe size %u\n", cxfer.pipe_size);
+
 	while (1) {
 		struct page_server_iov pi;
 		u32 cmd;
-- 
2.7.4



More information about the CRIU mailing list