Commit e297ab79 authored by Mike Rapoport's avatar Mike Rapoport Committed by Pavel Emelyanov

criu: page-pipe: introduce page_pipe_buf manipulation helpers

Signed-off-by: 's avatarMike Rapoport <rppt@linux.vnet.ibm.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent fa437b65
......@@ -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) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment