[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