[CRIU] [PATCH v5 1/8] criu: page-pipe: add ability to allocate IOVs

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


When collection of dumpee pages is followed by any parasite operation, we
cannot share iovs between parasite args area and page-pipe.
As a bonus we get some simplification of dump_one_shmem.

Signed-off-by: Mike Rapoport <rppt at linux.vnet.ibm.com>
---
 criu/include/page-pipe.h |  1 +
 criu/page-pipe.c         | 51 ++++++++++++++++++++++++++++++++----------------
 criu/shmem.c             | 11 ++---------
 3 files changed, 37 insertions(+), 26 deletions(-)

diff --git a/criu/include/page-pipe.h b/criu/include/page-pipe.h
index 696dc9f..ca129fd 100644
--- a/criu/include/page-pipe.h
+++ b/criu/include/page-pipe.h
@@ -95,6 +95,7 @@ struct page_pipe {
 
 	bool chunk_mode;	/* Restrict the maximum buffer size of pipes
 				   and dump memory for a few iterations */
+	bool own_iovs;		/* create_page_pipe allocated IOVs memory */
 };
 
 extern struct page_pipe *create_page_pipe(unsigned int nr,
diff --git a/criu/page-pipe.c b/criu/page-pipe.c
index 5faf155..b77381f 100644
--- a/criu/page-pipe.c
+++ b/criu/page-pipe.c
@@ -132,26 +132,41 @@ struct page_pipe *create_page_pipe(unsigned int nr_segs,
 
 	pr_debug("Create page pipe for %u segs\n", nr_segs);
 
-	pp = xmalloc(sizeof(*pp));
-	if (pp) {
-		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->nr_holes = 0;
-		pp->free_hole = 0;
-		pp->holes = NULL;
-
-		pp->chunk_mode = chunk_mode;
-
-		if (page_pipe_grow(pp, 0))
-			return NULL;
+	pp = xzalloc(sizeof(*pp));
+	if (!pp)
+		return NULL;
+
+	if (!iovs) {
+		iovs = xmalloc(sizeof(*iovs) * nr_segs);
+		if (!iovs)
+			goto err_free_pp;
+		pp->own_iovs = true;
 	}
 
+	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->nr_holes = 0;
+	pp->free_hole = 0;
+	pp->holes = NULL;
+
+	pp->chunk_mode = chunk_mode;
+
+	if (page_pipe_grow(pp, 0))
+		goto err_free_iovs;
+
 	return pp;
+
+err_free_iovs:
+	if (pp->own_iovs)
+		xfree(iovs);
+err_free_pp:
+	xfree(pp);
+	return NULL;
 }
 
 void destroy_page_pipe(struct page_pipe *pp)
@@ -164,6 +179,8 @@ void destroy_page_pipe(struct page_pipe *pp)
 	list_for_each_entry_safe(ppb, n, &pp->bufs, l)
 		ppb_destroy(ppb);
 
+	if (pp->own_iovs)
+		xfree(pp->iovs);
 	xfree(pp);
 }
 
diff --git a/criu/shmem.c b/criu/shmem.c
index f86a56a..ecedffb 100644
--- a/criu/shmem.c
+++ b/criu/shmem.c
@@ -529,7 +529,6 @@ static int dump_pages(struct page_pipe *pp, struct page_xfer *xfer, void *addr)
 
 static int dump_one_shmem(struct shmem_info *si)
 {
-	struct iovec *iovs;
 	struct page_pipe *pp;
 	struct page_xfer xfer;
 	int err, ret = -1, fd;
@@ -567,13 +566,9 @@ static int dump_one_shmem(struct shmem_info *si)
 	if (err)
 		goto err_unmap;
 
-	iovs = xmalloc(((nrpages + 1) / 2) * sizeof(struct iovec));
-	if (!iovs)
-		goto err_unmap;
-
-	pp = create_page_pipe((nrpages + 1) / 2, iovs, true);
+	pp = create_page_pipe((nrpages + 1) / 2, NULL, true);
 	if (!pp)
-		goto err_iovs;
+		goto err_unmap;
 
 	err = open_page_xfer(&xfer, CR_FD_SHMEM_PAGEMAP, si->shmid);
 	if (err)
@@ -600,8 +595,6 @@ err_xfer:
 	xfer.close(&xfer);
 err_pp:
 	destroy_page_pipe(pp);
-err_iovs:
-	xfree(iovs);
 err_unmap:
 	munmap(addr,  si->size);
 err:
-- 
1.9.1



More information about the CRIU mailing list