[CRIU] [PATCH v2 01/11] criu: page-pipe: introduce page_pipe_buf manipulation helpers
Mike Rapoport
rppt at linux.vnet.ibm.com
Tue May 31 06:34:51 PDT 2016
Signed-off-by: Mike Rapoport <rppt at linux.vnet.ibm.com>
---
criu/page-pipe.c | 85 +++++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 59 insertions(+), 26 deletions(-)
diff --git a/criu/page-pipe.c b/criu/page-pipe.c
index db58f6a..aad5905 100644
--- a/criu/page-pipe.c
+++ b/criu/page-pipe.c
@@ -25,6 +25,60 @@ 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, struct iovec *iov)
+{
+ ppb->pages_in = pages_in;
+ ppb->nr_segs = nr_segs;
+ 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)
{
struct page_pipe_buf *ppb;
@@ -40,24 +94,12 @@ static int page_pipe_grow(struct page_pipe *pp)
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->iov = &pp->iovs[pp->free_iov];
+ ppb_init(ppb, 0, 0, &pp->iovs[pp->free_iov]);
return 0;
}
@@ -98,11 +140,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);
}
@@ -134,15 +173,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