[CRIU] [PATCH 5/6] criu: pagemap: add PE_PRESENT flag

Mike Rapoport rppt at linux.vnet.ibm.com
Tue Sep 13 08:13:36 PDT 2016


On Tue, Sep 13, 2016 at 05:59:42PM +0300, Pavel Emelyanov wrote:
> 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...

If we dump lazy pages for e.g. lazy restore from images, the pagemaps with
lazy pages will have PE_PRESENT | PE_LAZY.
For post-copy, only PE_LAZY will be set and there won't be pages in
pages*img.

The idea is to make pagemap contain all the information to decide whether
uffd can/should be used during restore. Then we don't need to check each
time against VMA if certain page may be lazy.

 
> > 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