[CRIU] [PATCH] dedup: try add dedup on unmount vma, to auto-dedup and dedup

Pavel Emelyanov xemul at parallels.com
Mon Apr 14 04:20:23 PDT 2014


On 03/26/2014 06:54 PM, Tikhomirov Pavel wrote:
> Hi, this is an idea how we can do deduplication on unmount vma
> please watch and say if i'm in the wrong direction.
> 
> Thanks. Pavel.
> 
> main ides is: while going through parent pagemaps in dedup/dump we
> can punch pagemaps which are passed by
> 
> - fails becouse check_pagehole_in_parent and dedup_one_iovec won't
> seek to the end of checked\deduped area, so if this area is not at the
> end of parent pagemap entry, and end of parent pagemap intersects
> with non inparent pagemap it will dedup hole parent pagemap but need
> only last part. (cvaddr need to be at the end to do it right)
> 
> cur:   |--hole--|--data--|
> parent:    |--da.ta--|
> Signed-off-by: Tikhomirov Pavel <snorcht at gmail.com>

Patch "dedup: add dedup on unmap vma, into auto-dedup and dedup" was withdrawn
by you. Should I still consider this one for appying?

> ---
>  cr-dedup.c          | 11 +++++++++++
>  include/page-read.h |  1 +
>  page-read.c         | 24 ++++++++++++++++++++++++
>  page-xfer.c         |  2 +-
>  4 files changed, 37 insertions(+), 1 deletion(-)
> 
> diff --git a/cr-dedup.c b/cr-dedup.c
> index 7758674..e96ee40 100644
> --- a/cr-dedup.c
> +++ b/cr-dedup.c
> @@ -87,6 +87,17 @@ static int cr_dedup_one_pagemap(int pid)
>  			ret = dedup_one_iovec(prp, &iov);
>  			if (ret)
>  				goto exit;
> +		} else {
> +			/*
> +			 * If it is in parent go check it, check will use
> +			 * seek_pagemap_page, it does dedup of passed unmaped areas
> +			 */
> +			ret = check_pagehole_in_parent(prp, &iov);
> +			if (ret) {
> +				pr_err("Hole %p/%zu not found in parent\n",
> +							 iov.iov_base, iov.iov_len);
> +				goto exit;
> +			}
>  		}
>  
>  		pr.put_pagemap(&pr);
> diff --git a/include/page-read.h b/include/page-read.h
> index 7a063e9..3b8e496 100644
> --- a/include/page-read.h
> +++ b/include/page-read.h
> @@ -75,4 +75,5 @@ extern int seek_pagemap_page(struct page_read *pr, unsigned long vaddr, bool war
>  
>  extern int dedup_one_iovec(struct page_read *pr, struct iovec *iov);
>  extern int punch_hole(struct page_read *pr, unsigned long off, unsigned long len, bool cleanup);
> +extern int check_pagehole_in_parent(struct page_read *p, struct iovec *iov);
>  #endif /* __CR_PAGE_READ_H__ */
> diff --git a/page-read.c b/page-read.c
> index 8937f33..802015b 100644
> --- a/page-read.c
> +++ b/page-read.c
> @@ -101,6 +101,7 @@ int seek_pagemap_page(struct page_read *pr, unsigned long vaddr, bool warn)
>  
>  	while (1) {
>  		unsigned long iov_end;
> +		struct iovec tiov;
>  
>  		if (vaddr < pr->cvaddr) {
>  			if (warn)
> @@ -111,6 +112,19 @@ int seek_pagemap_page(struct page_read *pr, unsigned long vaddr, bool warn)
>  		iov_end = (unsigned long)iov.iov_base + iov.iov_len;
>  
>  		if (iov_end <= vaddr) {
> +			/*
> +			 * If pass through pagemap entry in parent, it was unmaped
> +			 * so we can dedup it
> +			 * pr->cvaddr is used to identify begining of unmaped block
> +			 * (end of previously checked region)
> +			 * but now it is wrong - need to redo!!!
> +			 */
> +			if (opts.auto_dedup) {
> +				tiov.iov_base = (void*)pr->cvaddr;
> +				tiov.iov_len = iov_end - pr->cvaddr;
> +				dedup_one_iovec(pr, &tiov);
> +			}
> +
>  			skip_pagemap_pages(pr, iov_end - pr->cvaddr);
>  			put_pagemap(pr);
>  new_pagemap:
> @@ -120,6 +134,16 @@ new_pagemap:
>  
>  			continue;
>  		}
> +		
> +		/*
> +		 * If pass through part of pagemap entry in parent, it was unmaped
> +		 * same for pr->cvaddr
> +		 */
> +		if (opts.auto_dedup) {
> +			tiov.iov_base = (void*)pr->cvaddr;
> +			tiov.iov_len = vaddr - pr->cvaddr;
> +			dedup_one_iovec(pr, &tiov);
> +		}
>  
>  		skip_pagemap_pages(pr, vaddr - pr->cvaddr);
>  		return 1;
> diff --git a/page-xfer.c b/page-xfer.c
> index f26be35..d0601f2 100644
> --- a/page-xfer.c
> +++ b/page-xfer.c
> @@ -487,7 +487,7 @@ static int write_pages_loc(struct page_xfer *xfer,
>  	return 0;
>  }
>  
> -static int check_pagehole_in_parent(struct page_read *p, struct iovec *iov)
> +int check_pagehole_in_parent(struct page_read *p, struct iovec *iov)
>  {
>  	int ret;
>  	unsigned long off, end;
> 




More information about the CRIU mailing list