[CRIU] [PATCH v5 3/8] criu: page-pipe: add a wrapping structure for holes and pages iovs

Mike Rapoport rppt at linux.vnet.ibm.com
Tue Jun 28 22:55:08 PDT 2016


The holes and actual pages iovs bookkeeping uses the same nr_X, free_X and
X pattern which could be wrapped by a structure. This structure will be
later reused for addition of zero-mapped pages to pagemap.

Signed-off-by: Mike Rapoport <rppt at linux.vnet.ibm.com>
---
 criu/include/page-pipe.h | 18 ++++++++++------
 criu/page-pipe.c         | 56 +++++++++++++++++++++++++-----------------------
 criu/page-xfer.c         |  8 +++----
 3 files changed, 44 insertions(+), 38 deletions(-)

diff --git a/criu/include/page-pipe.h b/criu/include/page-pipe.h
index ca129fd..a018af0 100644
--- a/criu/include/page-pipe.h
+++ b/criu/include/page-pipe.h
@@ -80,18 +80,22 @@ struct page_pipe_buf {
 	struct list_head l;	/* links into page_pipe->bufs */
 };
 
+struct page_pipe_iovs {
+	unsigned int nr_iovs;	/* number of iovs */
+	unsigned int free_iov;	/* number of iovs in use */
+	struct iovec *iovs;	/* iovs */
+};
+
 struct page_pipe {
 	unsigned int nr_pipes;	/* how many page_pipe_bufs in there */
 	struct list_head bufs;	/* list of bufs */
 	struct list_head free_bufs;	/* list of bufs */
-	unsigned int nr_iovs;	/* number of iovs */
-	unsigned int free_iov;	/* first free iov */
-	struct iovec *iovs;	/* iovs. They are provided into create_page_pipe
-				   and all bufs have their iov-s in there */
 
-	unsigned int nr_holes;	/* number of holes allocated */
-	unsigned int free_hole;	/* number of holes in use */
-	struct iovec *holes;	/* holes */
+	struct page_pipe_iovs pages;	/* iovs for pages. They are provided
+					   into create_page_pipe and all bufs
+					   have their iov-s in there */
+
+	struct page_pipe_iovs holes;	/* iovs for holes */
 
 	bool chunk_mode;	/* Restrict the maximum buffer size of pipes
 				   and dump memory for a few iterations */
diff --git a/criu/page-pipe.c b/criu/page-pipe.c
index b77381f..9bc7eaf 100644
--- a/criu/page-pipe.c
+++ b/criu/page-pipe.c
@@ -104,7 +104,7 @@ static int page_pipe_grow(struct page_pipe *pp, unsigned int flags)
 {
 	struct page_pipe_buf *ppb;
 
-	pr_debug("Will grow page pipe (iov off is %u)\n", pp->free_iov);
+	pr_debug("Will grow page pipe (iov off is %u)\n", pp->pages.free_iov);
 
 	if (!list_empty(&pp->free_bufs)) {
 		ppb = list_first_entry(&pp->free_bufs, struct page_pipe_buf, l);
@@ -120,7 +120,7 @@ static int page_pipe_grow(struct page_pipe *pp, unsigned int flags)
 		return -1;
 
 out:
-	ppb_init(ppb, 0, 0, flags, &pp->iovs[pp->free_iov]);
+	ppb_init(ppb, 0, 0, flags, &pp->pages.iovs[pp->pages.free_iov]);
 
 	return 0;
 }
@@ -146,13 +146,13 @@ struct page_pipe *create_page_pipe(unsigned int nr_segs,
 	pp->nr_pipes = 0;
 	INIT_LIST_HEAD(&pp->bufs);
 	INIT_LIST_HEAD(&pp->free_bufs);
-	pp->nr_iovs = nr_segs;
-	pp->iovs = iovs;
-	pp->free_iov = 0;
+	pp->pages.nr_iovs = nr_segs;
+	pp->pages.iovs = iovs;
+	pp->pages.free_iov = 0;
 
-	pp->nr_holes = 0;
-	pp->free_hole = 0;
-	pp->holes = NULL;
+	pp->holes.nr_iovs = 0;
+	pp->holes.free_iov = 0;
+	pp->holes.iovs = NULL;
 
 	pp->chunk_mode = chunk_mode;
 
@@ -180,7 +180,7 @@ void destroy_page_pipe(struct page_pipe *pp)
 		ppb_destroy(ppb);
 
 	if (pp->own_iovs)
-		xfree(pp->iovs);
+		xfree(pp->pages.iovs);
 	xfree(pp);
 }
 
@@ -195,7 +195,7 @@ void page_pipe_reinit(struct page_pipe *pp)
 	list_for_each_entry_safe(ppb, n, &pp->bufs, l)
 		list_move(&ppb->l, &pp->free_bufs);
 
-	pp->free_hole = 0;
+	pp->holes.free_iov = 0;
 
 	if (page_pipe_grow(pp, 0))
 		BUG(); /* It can't fail, because ppb is in free_bufs */
@@ -229,10 +229,10 @@ static inline int try_add_page_to(struct page_pipe *pp, struct page_pipe_buf *pp
 	}
 
 	pr_debug("Add iov to page pipe (%u iovs, %u/%u total)\n",
-			ppb->nr_segs, pp->free_iov, pp->nr_iovs);
+			ppb->nr_segs, pp->pages.free_iov, pp->pages.nr_iovs);
 	iov_init(&ppb->iov[ppb->nr_segs++], addr);
-	pp->free_iov++;
-	BUG_ON(pp->free_iov > pp->nr_iovs);
+	pp->pages.free_iov++;
+	BUG_ON(pp->pages.free_iov > pp->pages.nr_iovs);
 out:
 	ppb->pages_in++;
 	return 0;
@@ -267,20 +267,22 @@ int page_pipe_add_page(struct page_pipe *pp, unsigned long addr,
 
 int page_pipe_add_hole(struct page_pipe *pp, unsigned long addr)
 {
-	if (pp->free_hole >= pp->nr_holes) {
-		pp->holes = xrealloc(pp->holes,
-				(pp->nr_holes + PP_HOLES_BATCH) * sizeof(struct iovec));
-		if (!pp->holes)
+	struct page_pipe_iovs *hole = &pp->holes;
+
+	if (hole->free_iov >= hole->nr_iovs) {
+		hole->iovs = xrealloc(hole->iovs,
+				(hole->nr_iovs + PP_HOLES_BATCH) * sizeof(struct iovec));
+		if (!hole->iovs)
 			return -1;
 
-		pp->nr_holes += PP_HOLES_BATCH;
+		hole->nr_iovs += PP_HOLES_BATCH;
 	}
 
-	if (pp->free_hole &&
-			iov_grow_page(&pp->holes[pp->free_hole - 1], addr))
+	if (hole->free_iov &&
+			iov_grow_page(&hole->iovs[hole->free_iov - 1], addr))
 		goto out;
 
-	iov_init(&pp->holes[pp->free_hole++], addr);
+	iov_init(&hole->iovs[hole->free_iov++], addr);
 out:
 	return 0;
 }
@@ -338,8 +340,8 @@ static int page_pipe_split_iov(struct page_pipe *pp, struct page_pipe_buf *ppb,
 	if (ret != len)
 		return -1;
 
-	iov_new = &pp->iovs[pp->free_iov++];
-	BUG_ON(pp->free_iov > pp->nr_iovs);
+	iov_new = &pp->pages.iovs[pp->pages.free_iov++];
+	BUG_ON(pp->pages.free_iov > pp->pages.nr_iovs);
 	iov_new->iov_base = iov->iov_base;
 	iov_new->iov_len = len;
 
@@ -457,7 +459,7 @@ void debug_show_page_pipe(struct page_pipe *pp)
 
 	pr_debug("Page pipe:\n");
 	pr_debug("* %u pipes %u/%u iovs:\n",
-			pp->nr_pipes, pp->free_iov, pp->nr_iovs);
+			pp->nr_pipes, pp->pages.free_iov, pp->pages.nr_iovs);
 	list_for_each_entry(ppb, &pp->bufs, l) {
 		pr_debug("\tbuf %u pages, %u iovs, flags: %x :\n",
 			 ppb->pages_in, ppb->nr_segs, ppb->flags);
@@ -467,9 +469,9 @@ void debug_show_page_pipe(struct page_pipe *pp)
 		}
 	}
 
-	pr_debug("* %u holes:\n", pp->free_hole);
-	for (i = 0; i < pp->free_hole; i++) {
-		iov = &pp->holes[i];
+	pr_debug("* %u holes:\n", pp->holes.free_iov);
+	for (i = 0; i < pp->holes.free_iov; i++) {
+		iov = &pp->holes.iovs[i];
 		pr_debug("\t%p %lu\n", iov->iov_base, iov->iov_len / PAGE_SIZE);
 	}
 }
diff --git a/criu/page-xfer.c b/criu/page-xfer.c
index 3813712..4bb8ea0 100644
--- a/criu/page-xfer.c
+++ b/criu/page-xfer.c
@@ -328,8 +328,8 @@ int page_xfer_dump_pages(struct page_xfer *xfer, struct page_pipe *pp,
 
 	pr_debug("Transfering pages:\n");
 
-	if (pp->free_hole)
-		hole = &pp->holes[0];
+	if (pp->holes.free_iov)
+		hole = &pp->holes.iovs[0];
 
 	list_for_each_entry(ppb, &pp->bufs, l) {
 		int i;
@@ -348,7 +348,7 @@ int page_xfer_dump_pages(struct page_xfer *xfer, struct page_pipe *pp,
 					return -1;
 
 				hole++;
-				if (hole >= &pp->holes[pp->free_hole])
+				if (hole >= &pp->holes.iovs[pp->holes.free_iov])
 					hole = NULL;
 			}
 
@@ -373,7 +373,7 @@ int page_xfer_dump_pages(struct page_xfer *xfer, struct page_pipe *pp,
 			return -1;
 
 		hole++;
-		if (hole >= &pp->holes[pp->free_hole])
+		if (hole >= &pp->holes.iovs[pp->holes.free_iov])
 			hole = NULL;
 	}
 
-- 
1.9.1



More information about the CRIU mailing list