[CRIU] [PATCH 5/6] criu: pagemap: add PE_PRESENT flag
Pavel Emelyanov
xemul at virtuozzo.com
Tue Sep 13 07:59:42 PDT 2016
On 09/08/2016 10:39 AM, Mike Rapoport wrote:
> The PE_PRESENT flags is always set for pagemap entries that have
> corresponding pages in the pages*img. Pagemap entries describing a hole
> either with zero page or with pages in the parent snapshot will no have
> PE_PRESENT flag set.
But why do we need the separate flag then? If entry.flag & (PE_ZERO | PE_LAZY)
is equivalent to it...
> Pagemap entry that may be lazily restored is a special case. For the lazy
> restore from disk case, both PE_LAZY and PE_PRESENT will be set in the
> pagemap, but for the remote lazy pages case only PE_LAZY will be set.
>
> Signed-off-by: Mike Rapoport <rppt at linux.vnet.ibm.com>
> ---
> criu/include/pagemap.h | 6 ++++++
> criu/page-xfer.c | 16 +++++++++++-----
> criu/pagemap.c | 10 +++++++++-
> 3 files changed, 26 insertions(+), 6 deletions(-)
>
> diff --git a/criu/include/pagemap.h b/criu/include/pagemap.h
> index f4a9285..705a9af 100644
> --- a/criu/include/pagemap.h
> +++ b/criu/include/pagemap.h
> @@ -97,6 +97,7 @@ extern int dedup_one_iovec(struct page_read *pr, struct iovec *iov);
> #define PE_PARENT (1 << 0) /* pages are in parent snapshot */
> #define PE_ZERO (1 << 1) /* pages can be lazily restored */
> #define PE_LAZY (1 << 2) /* pages are mapped to zero pfn */
> +#define PE_PRESENT (1 << 3) /* pages are present in pages*img */
>
> static inline bool pagemap_in_parent(PagemapEntry *pe)
> {
> @@ -113,4 +114,9 @@ static inline bool pagemap_lazy(PagemapEntry *pe)
> return !!(pe->flags & PE_LAZY);
> }
>
> +static inline bool pagemap_present(PagemapEntry *pe)
> +{
> + return !!(pe->flags & PE_PRESENT);
> +}
> +
> #endif /* __CR_PAGE_READ_H__ */
> diff --git a/criu/page-xfer.c b/criu/page-xfer.c
> index 68dba86..798ea0b 100644
> --- a/criu/page-xfer.c
> +++ b/criu/page-xfer.c
> @@ -440,6 +440,7 @@ int page_xfer_dump_pages(struct page_xfer *xfer, struct page_pipe *pp,
>
> for (i = 0; i < ppb->nr_segs; i++) {
> struct iovec iov = get_iov(ppb->iov, i, pp->flags & PP_COMPAT);
> + u32 flags = PE_PRESENT;
>
> ret = dump_holes(xfer, pp, &cur_hole, iov.iov_base, off);
> if (ret)
> @@ -450,13 +451,18 @@ int page_xfer_dump_pages(struct page_xfer *xfer, struct page_pipe *pp,
> pr_debug("\tp %p [%u]\n", iov.iov_base,
> (unsigned int)(iov.iov_len / PAGE_SIZE));
>
> - if (!dump_lazy && ppb->flags & PPB_LAZY) {
> - if (xfer->write_hole(xfer, &iov, PS_IOV_LAZY))
> - return -1;
> - continue;
> + if (ppb->flags & PPB_LAZY) {
> + if (!dump_lazy) {
> + if (xfer->write_hole(xfer, &iov,
> + PS_IOV_LAZY))
> + return -1;
> + continue;
> + } else {
> + flags |= PE_LAZY;
> + }
> }
>
> - if (xfer->write_pagemap(xfer, &iov, 0))
> + if (xfer->write_pagemap(xfer, &iov, flags))
> return -1;
> if (xfer->write_pages(xfer, ppb->p[0], iov.iov_len))
> return -1;
> diff --git a/criu/pagemap.c b/criu/pagemap.c
> index aaef5a4..71ae11e 100644
> --- a/criu/pagemap.c
> +++ b/criu/pagemap.c
> @@ -158,7 +158,7 @@ static void skip_pagemap_pages(struct page_read *pr, unsigned long len)
> return;
>
> pr_debug("\tpr%u Skip %lu bytes from page-dump\n", pr->id, len);
> - if (!pagemap_in_parent(pr->pe) && !pagemap_zero(pr->pe) && !pagemap_lazy(pr->pe))
> + if (pagemap_present(pr->pe))
> pr->pi_off += len;
> pr->cvaddr += len;
> }
> @@ -360,8 +360,16 @@ err_cl:
>
> static void init_compat_pagemap_entry(PagemapEntry *pe)
> {
> + /*
> + * pagemap image generated with older version will either
> + * contain a hole because the pages are in the parent
> + * shanpshot or a pagemap that should be marked with
> + * PE_PRESENT
> + */
> if (pe->has_in_parent && pe->in_parent)
> pe->flags |= PE_PARENT;
> + else if (!pe->has_flags)
> + pe->flags = PE_PRESENT;
> }
>
> /*
>
More information about the CRIU
mailing list