[CRIU] [PATCH v3 2/2] lazy-pages: add support to combine pre-copy and post-copy

Adrian Reber adrian at lisas.de
Wed Sep 21 23:50:59 PDT 2016


On Wed, Sep 21, 2016 at 09:44:49AM +0300, Mike Rapoport wrote:
> Hi Adrian,
> 
> On Tue, Sep 20, 2016 at 06:54:11PM +0200, Adrian Reber wrote:
> > From: Adrian Reber <areber at redhat.com>
>  
> [snip]
>  
> > v2:
> >  - changed parent detection to use pagemap_in_parent()
> > 
> > v3:
> >  - unfortunately this reverts
> >    c11cf95afbe023a2816a3afaecb65cc4fee670d7
> >    "criu: mem: skip lazy pages during restore based on pagemap info"
> >    To be able to split the VMA-s in the right chunks for the restorer
> >    it is necessary to make the decision lazy or not on the VmaEntry
> >    level.
> 
> I've thought a little bit more about it and I'm not sure it is necessary to
> split VMAs at all. The restorer can register the entire VMA with
> userfaultfd, even if the VMA contains pages that are already restored. We
> just need to make sure uffd.c can properly handle -EEXITS case and it seems
> we are good.
> 
> Consider the following scenario:
> There is a VMA that spawns from 0x10000 to 0x20000 (16 pages). Let's say
> that the range from 0x10000 to 0x1a000 is dumped during pre-dump and there
> were no changes in that memory, so during dump the range 0x10000 - 0x1a0000
> will be marked with PE_PARENT, and the range 0x1a000 - 0x20000 will be
> marked PE_LAZY.
> During restore, the range marked as PE_PARENT will be filled with the
> content from the disk image and the range marked PE_LAZY will remain
> unpopulated.
> restorer will register the entire VMA (0x10000 - 0x20000) with userfaultfd
> and lazy-pages daemon will consider the entire range as lazy.
> However, the pages at 0x10000 - 0x1a000 are already present, therefore
> access to these pages won't cause a page fault.
> When, at last lazy-pages daemon will try to restore the range 0x10000 - 0x1a000
> during handle_remaining_pages stage, it'll get -EEXISTS from userfaultfd.

So I actually tested it and it works without all the VMA splitting.

> Sorry I've come really late with this and created some hassle for you...

Yes, it is kind of frustrating to have written all the VMA splitting
code to have it replaced by a two line change ;-) Anyway...

>From the following patch only this is necessary:

> > --- a/criu/uffd.c
> > +++ b/criu/uffd.c
> > @@ -508,7 +508,8 @@ static int collect_uffd_pages(struct page_read *pr, struct lazy_pages_info *lpi)
> >  			 */
> >  			if (base >= vma->e->start && base < vma->e->end) {
> >  				if (vma_entry_can_be_lazy(vma->e)) {
> > -					uffd_page = true;
> > +					if(!pagemap_in_parent(pr->pe))
> > +						uffd_page = true;
> >  					break;
> >  				}
> >  			}

I will post a new version of the patch with only this change. Thanks for
pointing out how to simplify this.

		Adrian


More information about the CRIU mailing list