[CRIU] [PATCH 2/3] page-xfer: remote-pages: allow receiving partial data

Mike Rapoport rppt at linux.vnet.ibm.com
Thu Nov 16 14:54:06 MSK 2017


Since commit e609267f681062b4370e528a50f635222e0c2330 ("page-pipe: allow to
share pipes between page pipe buffers") the assumption that we will receive
the exact amount of pages we've requested with PS_IOV_GET does not always
hold.
In the case we serve pages data from the images using 'page-server
--lazy-page' the IOVs seen by the pagemap may cross page-pipe buffer
boundaries and read_page_pipe will clamp the pages in the response to those
boundaries.
Adjust page_server_read so it will not try to receive more pages than
page-server is going to send.

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

diff --git a/criu/page-xfer.c b/criu/page-xfer.c
index aad4257..0215dfd 100644
--- a/criu/page-xfer.c
+++ b/criu/page-xfer.c
@@ -1106,6 +1106,7 @@ out:
 struct ps_async_read {
 	unsigned long rb; /* read bytes */
 	unsigned long goal;
+	unsigned long nr_pages;
 
 	struct page_server_iov pi;
 	void *pages;
@@ -1118,14 +1119,20 @@ struct ps_async_read {
 
 static LIST_HEAD(async_reads);
 
+static inline void async_read_set_goal(struct ps_async_read *ar, int nr_pages)
+{
+	ar->goal = sizeof(ar->pi) + nr_pages * PAGE_SIZE;
+	ar->nr_pages = nr_pages;
+}
+
 static void init_ps_async_read(struct ps_async_read *ar, void *buf,
 		int nr_pages, ps_async_read_complete complete, void *priv)
 {
 	ar->pages = buf;
 	ar->rb = 0;
-	ar->goal = sizeof(ar->pi) + nr_pages * PAGE_SIZE;
 	ar->complete = complete;
 	ar->priv = priv;
+	async_read_set_goal(ar, nr_pages);
 }
 
 static int page_server_start_async_read(void *buf, int nr_pages,
@@ -1161,6 +1168,9 @@ static int page_server_read(struct ps_async_read *ar, int flags)
 		buf = ((void *)&ar->pi) + ar->rb;
 		need = sizeof(ar->pi) - ar->rb;
 	} else {
+		/* page-serer may return less pages than we asked for */
+		if (ar->pi.nr_pages < ar->nr_pages)
+			async_read_set_goal(ar, ar->pi.nr_pages);
 		/* Page(s) data itself */
 		buf = ar->pages + (ar->rb - sizeof(ar->pi));
 		need = ar->goal - ar->rb;
-- 
2.7.4



More information about the CRIU mailing list