[CRIU] [PATCH 1/2] page-pipe: correctly split page-pipe-buffers

Mike Rapoport rppt at linux.vnet.ibm.com
Wed Sep 7 23:45:34 PDT 2016


Hi Adrian,

On Wed, Sep 07, 2016 at 06:24:31PM +0200, Adrian Reber wrote:
> From: Adrian Reber <areber at redhat.com>
> 
> Combining pre-copy (pre-dump) and post-copy (lazy-pages) mode showed a
> problem in the function page_pipe_split_ppb(). The function is used to
> split the page-pipe-buffer so that it only contains the IOVs request
> from the restore side during lazy restore.
> 
> Unfortunately it only splits the leading IOVs out of the
> page-pipe-buffer and not the trailing:

Thanks a lot for the fix!
Some nitpicking comments below ;-)
 
> Before split for requested address 0x7f27284d1000:
> 
>  page-pipe: ppb->iov 0x7f0f74d93040
>  page-pipe: 		0x7f27282bb000 1
>  page-pipe: 		0x7f27284d1000 1
>  page-pipe: 		0x7f27284dd000 2
> 
> After split:
> 
>  page-pipe: ppb->iov 0x7f0f74d93050
>  page-pipe: 		0x7f27284d1000 1
>  page-pipe: 		0x7f27284dd000 2
> 
> and:
> 
>  page-pipe: ppb->iov 0x7f0f74d93040
>  page-pipe: 		0x7f27282bb000 1
> 
> This patch keeps on splitting the page-pipe-buffer until it contains
> only the requested address with the requested length.
> 
> After split (still trying to load 0x7f27284d1000):
> 
>  page-pipe: ppb->iov 0x7f0f74d93050
>  page-pipe: 		0x7f27284d1000 1
> 
> and:
> 
>  page-pipe: ppb->iov 0x7f0f74d93040
>  page-pipe: 		0x7f27282bb000 1
> 
> and:
> 
>  page-pipe: ppb->iov 0x7f0f74d93060
>  page-pipe: 		0x7f27284dd000 2
> 
> Signed-off-by: Adrian Reber <areber at redhat.com>
> ---
>  criu/page-pipe.c | 31 +++++++++++++++++++++++++++++++
>  1 file changed, 31 insertions(+)
> 
> diff --git a/criu/page-pipe.c b/criu/page-pipe.c
> index df028dc..52be88c 100644
> --- a/criu/page-pipe.c
> +++ b/criu/page-pipe.c
> @@ -412,6 +412,37 @@ static int page_pipe_split_ppb(struct page_pipe *pp, struct page_pipe_buf *ppb,
> 
>  	list_move(&ppb->l, &pp->bufs);
> 
> +	/*
> +	 * Only the leading iov's are split from the page_pipe_buffer.
> +	 * The complete page_pipe_buffer at the start of the page_pipe
> +	 * list will be deleted and therefore it is necessary to also
> +	 * move unrelated iov's to their own page_pipe_buffers.
> +	 */
> +
> +	if (ppb->nr_segs <= len / PAGE_SIZE)
> +		return 0;
> +
> +	struct page_pipe_buf *ppb_tmp;
> +	struct iovec *iov_tmp = iov;

I think the declarations should go to the declarations block in the
beginning of the function.

> +
> +	/* Move to the iov after the current request */
> +	iov += len / PAGE_SIZE;
> +	ret = page_pipe_split_ppb(pp, ppb, iov, len);
> +	if (ret)
> +		return -1;
> +
> +	/*
> +	 * Rotate until correct head pointer. The function transmitting
> +	 * the page data expects that the head points to the right
> +	 * page_pipe_buffer. The complete first page_pipe_buffer is
> +	 * deleted even it contains additional elements.
> +	 */
> +	ppb_tmp = list_first_entry(&pp->bufs, struct page_pipe_buf, l);
> +	while (ppb_tmp->iov != iov_tmp) {
> +		list_rotate_left(&pp->bufs);
> +		ppb_tmp = list_first_entry(&pp->bufs, struct page_pipe_buf, l);
> +	}
> +
>  	return 0;
>  }
 
-- 
Sincerely yours,
Mike.



More information about the CRIU mailing list