[CRIU] [PATCH RFC 3/8] criu: page-pipe: introduce page_pipe_buf manipulation helpers

Mike Rapoport rppt at linux.vnet.ibm.com
Sat May 21 03:49:37 PDT 2016


Signed-off-by: Mike Rapoport <rppt at linux.vnet.ibm.com>
---
 criu/page-pipe.c | 88 +++++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 61 insertions(+), 27 deletions(-)

diff --git a/criu/page-pipe.c b/criu/page-pipe.c
index 78f8271..ccafea0 100644
--- a/criu/page-pipe.c
+++ b/criu/page-pipe.c
@@ -25,6 +25,62 @@ static inline void iov_init(struct iovec *iov, unsigned long addr)
 	iov->iov_len = PAGE_SIZE;
 }
 
+static struct page_pipe_buf *ppb_alloc(struct page_pipe *pp)
+{
+	struct page_pipe_buf *ppb;
+
+	ppb = xmalloc(sizeof(*ppb));
+	if (!ppb)
+		return NULL;
+
+	if (pipe(ppb->p)) {
+		xfree(ppb);
+		pr_perror("Can't make pipe for page-pipe");
+		return NULL;
+	}
+
+	ppb->pipe_size = fcntl(ppb->p[0], F_GETPIPE_SZ, 0) / PAGE_SIZE;
+	pp->nr_pipes++;
+
+	list_add_tail(&ppb->l, &pp->bufs);
+
+	return ppb;
+}
+
+static void ppb_destroy(struct page_pipe_buf *ppb)
+{
+	close(ppb->p[0]);
+	close(ppb->p[1]);
+	xfree(ppb);
+}
+
+static void ppb_init(struct page_pipe_buf *ppb, unsigned int pages_in,
+		     unsigned int nr_segs, unsigned int flags,
+		     struct iovec *iov)
+{
+	ppb->pages_in = pages_in;
+	ppb->nr_segs = nr_segs;
+	ppb->flags = flags;
+	ppb->iov = iov;
+}
+
+static int ppb_resize_pipe(struct page_pipe_buf *ppb, unsigned long new_size)
+{
+	int ret;
+
+	ret = fcntl(ppb->p[0], F_SETPIPE_SZ, new_size * PAGE_SIZE);
+	if (ret < 0)
+		return -1;
+
+	ret /= PAGE_SIZE;
+	BUG_ON(ret < ppb->pipe_size);
+
+	pr_debug("Grow pipe %x -> %x\n", ppb->pipe_size, ret);
+	ppb->pipe_size = ret;
+
+	return 0;
+}
+
 static int page_pipe_grow(struct page_pipe *pp, unsigned int flags)
 {
 	struct page_pipe_buf *ppb;
@@ -40,25 +96,12 @@ static int page_pipe_grow(struct page_pipe *pp, unsigned int flags)
 	if (pp->chunk_mode && pp->nr_pipes == NR_PIPES_PER_CHUNK)
 		return -EAGAIN;
 
-	ppb = xmalloc(sizeof(*ppb));
+	ppb = ppb_alloc(pp);
 	if (!ppb)
 		return -1;
 
-	if (pipe(ppb->p)) {
-		xfree(ppb);
-		pr_perror("Can't make pipe for page-pipe");
-		return -1;
-	}
-
-	ppb->pipe_size = fcntl(ppb->p[0], F_GETPIPE_SZ, 0) / PAGE_SIZE;
-	pp->nr_pipes++;
-
-	list_add_tail(&ppb->l, &pp->bufs);
 out:
-	ppb->pages_in = 0;
-	ppb->nr_segs = 0;
-	ppb->flags = flags;
-	ppb->iov = &pp->iovs[pp->free_iov];
+	ppb_init(ppb, 0, 0, flags, &pp->iovs[pp->free_iov]);
 
 	return 0;
 }
@@ -99,11 +142,8 @@ void destroy_page_pipe(struct page_pipe *pp)
 	pr_debug("Killing page pipe\n");
 
 	list_splice(&pp->free_bufs, &pp->bufs);
-	list_for_each_entry_safe(ppb, n, &pp->bufs, l) {
-		close(ppb->p[0]);
-		close(ppb->p[1]);
-		xfree(ppb);
-	}
+	list_for_each_entry_safe(ppb, n, &pp->bufs, l)
+		ppb_destroy(ppb);
 
 	xfree(pp);
 }
@@ -138,15 +178,9 @@ static inline int try_add_page_to(struct page_pipe *pp, struct page_pipe_buf *pp
 		if (new_size > PIPE_MAX_SIZE)
 			return 1;
 
-		ret = fcntl(ppb->p[0], F_SETPIPE_SZ, new_size * PAGE_SIZE);
+		ret = ppb_resize_pipe(ppb, new_size);
 		if (ret < 0)
 			return 1; /* need to add another buf */
-
-		ret /= PAGE_SIZE;
-		BUG_ON(ret < ppb->pipe_size);
-
-		pr_debug("Grow pipe %x -> %x\n", ppb->pipe_size, ret);
-		ppb->pipe_size = ret;
 	}
 
 	if (ppb->nr_segs) {
-- 
1.9.1



More information about the CRIU mailing list