[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