[CRIU] [PATCH RFC 2/8] criu: page_pipe_buf: add PPB_LAZY flag
Pavel Emelyanov
xemul at virtuozzo.com
Fri May 27 12:26:53 PDT 2016
On 05/21/2016 01:49 PM, Mike Rapoport wrote:
> for buffers that contain potentially lazy pages
But... Why a buffer would contain lazy pages?
> Signed-off-by: Mike Rapoport <rppt at linux.vnet.ibm.com>
> ---
> criu/include/page-pipe.h | 5 ++++-
> criu/mem.c | 6 +++++-
> criu/page-pipe.c | 30 ++++++++++++++++++------------
> criu/shmem.c | 2 +-
> 4 files changed, 28 insertions(+), 15 deletions(-)
>
> diff --git a/criu/include/page-pipe.h b/criu/include/page-pipe.h
> index a2dc268..031f145 100644
> --- a/criu/include/page-pipe.h
> +++ b/criu/include/page-pipe.h
> @@ -74,6 +74,8 @@ struct page_pipe_buf {
> unsigned int pipe_size; /* how many pages can be fit into pipe */
> unsigned int pages_in; /* how many pages are there */
> unsigned int nr_segs; /* how many iov-s are busy */
> +#define PPB_LAZY (1 << 0)
> + unsigned int flags;
> struct iovec *iov; /* vaddr:len map */
> struct list_head l; /* links into page_pipe->bufs */
> };
> @@ -98,7 +100,8 @@ struct page_pipe {
> extern struct page_pipe *create_page_pipe(unsigned int nr,
> struct iovec *, bool chunk_mode);
> extern void destroy_page_pipe(struct page_pipe *p);
> -extern int page_pipe_add_page(struct page_pipe *p, unsigned long addr);
> +extern int page_pipe_add_page(struct page_pipe *p, unsigned long addr,
> + unsigned int flags);
> extern int page_pipe_add_hole(struct page_pipe *p, unsigned long addr);
>
> extern void debug_show_page_pipe(struct page_pipe *pp);
> diff --git a/criu/mem.c b/criu/mem.c
> index becbd6d..0497975 100644
> --- a/criu/mem.c
> +++ b/criu/mem.c
> @@ -137,6 +137,7 @@ static int generate_iovs(struct vma_area *vma, struct page_pipe *pp, u64 *map, u
>
> for (pfn = 0; pfn < nr_to_scan; pfn++) {
> unsigned long vaddr;
> + unsigned int ppb_flags = 0;
> int ret;
>
> if (!should_dump_page(vma->e, at[pfn]))
> @@ -144,6 +145,9 @@ static int generate_iovs(struct vma_area *vma, struct page_pipe *pp, u64 *map, u
>
> vaddr = vma->e->start + *off + pfn * PAGE_SIZE;
>
> + if (vma_entry_can_be_lazy(vma->e))
> + ppb_flags |= PPB_LAZY;
> +
> /*
> * If we're doing incremental dump (parent images
> * specified) and page is not soft-dirty -- we dump
> @@ -155,7 +159,7 @@ static int generate_iovs(struct vma_area *vma, struct page_pipe *pp, u64 *map, u
> ret = page_pipe_add_hole(pp, vaddr);
> pages[0]++;
> } else {
> - ret = page_pipe_add_page(pp, vaddr);
> + ret = page_pipe_add_page(pp, vaddr, ppb_flags);
> pages[1]++;
> }
>
> diff --git a/criu/page-pipe.c b/criu/page-pipe.c
> index db58f6a..78f8271 100644
> --- a/criu/page-pipe.c
> +++ b/criu/page-pipe.c
> @@ -25,7 +25,7 @@ static inline void iov_init(struct iovec *iov, unsigned long addr)
> iov->iov_len = PAGE_SIZE;
> }
>
> -static int page_pipe_grow(struct page_pipe *pp)
> +static int page_pipe_grow(struct page_pipe *pp, unsigned int flags)
> {
> struct page_pipe_buf *ppb;
>
> @@ -57,6 +57,7 @@ static int page_pipe_grow(struct page_pipe *pp)
> out:
> ppb->pages_in = 0;
> ppb->nr_segs = 0;
> + ppb->flags = flags;
> ppb->iov = &pp->iovs[pp->free_iov];
>
> return 0;
> @@ -84,7 +85,7 @@ struct page_pipe *create_page_pipe(unsigned int nr_segs,
>
> pp->chunk_mode = chunk_mode;
>
> - if (page_pipe_grow(pp))
> + if (page_pipe_grow(pp, 0))
> return NULL;
> }
>
> @@ -120,13 +121,16 @@ void page_pipe_reinit(struct page_pipe *pp)
>
> pp->free_hole = 0;
>
> - if (page_pipe_grow(pp))
> + if (page_pipe_grow(pp, 0))
> BUG(); /* It can't fail, because ppb is in free_bufs */
> }
>
> static inline int try_add_page_to(struct page_pipe *pp, struct page_pipe_buf *ppb,
> - unsigned long addr)
> + unsigned long addr, unsigned int flags)
> {
> + if (ppb->flags != flags)
> + return 1;
> +
> if (ppb->pages_in == ppb->pipe_size) {
> unsigned long new_size = ppb->pipe_size << 1;
> int ret;
> @@ -164,25 +168,27 @@ out:
> return 0;
> }
>
> -static inline int try_add_page(struct page_pipe *pp, unsigned long addr)
> +static inline int try_add_page(struct page_pipe *pp, unsigned long addr,
> + unsigned int flags)
> {
> BUG_ON(list_empty(&pp->bufs));
> - return try_add_page_to(pp, list_entry(pp->bufs.prev, struct page_pipe_buf, l), addr);
> + return try_add_page_to(pp, list_entry(pp->bufs.prev, struct page_pipe_buf, l), addr, flags);
> }
>
> -int page_pipe_add_page(struct page_pipe *pp, unsigned long addr)
> +int page_pipe_add_page(struct page_pipe *pp, unsigned long addr,
> + unsigned int flags)
> {
> int ret;
>
> - ret = try_add_page(pp, addr);
> + ret = try_add_page(pp, addr, flags);
> if (ret <= 0)
> return ret;
>
> - ret = page_pipe_grow(pp);
> + ret = page_pipe_grow(pp, flags);
> if (ret < 0)
> return ret;
>
> - ret = try_add_page(pp, addr);
> + ret = try_add_page(pp, addr, flags);
> BUG_ON(ret > 0);
> return ret;
> }
> @@ -222,8 +228,8 @@ void debug_show_page_pipe(struct page_pipe *pp)
> pr_debug("* %u pipes %u/%u iovs:\n",
> pp->nr_pipes, pp->free_iov, pp->nr_iovs);
> list_for_each_entry(ppb, &pp->bufs, l) {
> - pr_debug("\tbuf %u pages, %u iovs:\n",
> - ppb->pages_in, ppb->nr_segs);
> + pr_debug("\tbuf %u pages, %u iovs, flags: %x :\n",
> + ppb->pages_in, ppb->nr_segs, ppb->flags);
> for (i = 0; i < ppb->nr_segs; i++) {
> iov = &ppb->iov[i];
> pr_debug("\t\t%p %lu\n", iov->iov_base, iov->iov_len / PAGE_SIZE);
> diff --git a/criu/shmem.c b/criu/shmem.c
> index 493477e..05458c7 100644
> --- a/criu/shmem.c
> +++ b/criu/shmem.c
> @@ -405,7 +405,7 @@ static int dump_one_shmem(struct shmem_info_dump *si)
> if (!(map[pfn] & PAGE_RSS))
> continue;
> again:
> - ret = page_pipe_add_page(pp, (unsigned long)addr + pfn * PAGE_SIZE);
> + ret = page_pipe_add_page(pp, (unsigned long)addr + pfn * PAGE_SIZE, 0);
> if (ret == -EAGAIN) {
> ret = dump_pages(pp, &xfer, addr);
> if (ret)
>
More information about the CRIU
mailing list