[v5,4/8] criu: page-{pipe, xfer}: add helper function for dumping holes

Submitted by Mike Rapoport on June 29, 2016, 5:55 a.m.

Details

Message ID 1467179713-14400-5-git-send-email-rppt@linux.vnet.ibm.com
State Rejected
Series "criu: make pagemap friendlier to random access"
Headers show

Commit Message

Mike Rapoport June 29, 2016, 5:55 a.m.
Signed-off-by: Mike Rapoport <rppt@linux.vnet.ibm.com>
---
 criu/include/page-pipe.h |  1 +
 criu/page-pipe.c         |  2 ++
 criu/page-xfer.c         | 54 +++++++++++++++++++++++-------------------------
 3 files changed, 29 insertions(+), 28 deletions(-)

Patch hide | download patch | download mbox

diff --git a/criu/include/page-pipe.h b/criu/include/page-pipe.h
index a018af0..f11071c 100644
--- a/criu/include/page-pipe.h
+++ b/criu/include/page-pipe.h
@@ -83,6 +83,7 @@  struct page_pipe_buf {
 struct page_pipe_iovs {
 	unsigned int nr_iovs;	/* number of iovs */
 	unsigned int free_iov;	/* number of iovs in use */
+	unsigned int busy_iov;	/* first iov that not yet dumped */
 	struct iovec *iovs;	/* iovs */
 };
 
diff --git a/criu/page-pipe.c b/criu/page-pipe.c
index 9bc7eaf..d002c3a 100644
--- a/criu/page-pipe.c
+++ b/criu/page-pipe.c
@@ -149,10 +149,12 @@  struct page_pipe *create_page_pipe(unsigned int nr_segs,
 	pp->pages.nr_iovs = nr_segs;
 	pp->pages.iovs = iovs;
 	pp->pages.free_iov = 0;
+	pp->pages.busy_iov = 0;
 
 	pp->holes.nr_iovs = 0;
 	pp->holes.free_iov = 0;
 	pp->holes.iovs = NULL;
+	pp->holes.busy_iov = 0;
 
 	pp->chunk_mode = chunk_mode;
 
diff --git a/criu/page-xfer.c b/criu/page-xfer.c
index 4bb8ea0..32b50f7 100644
--- a/criu/page-xfer.c
+++ b/criu/page-xfer.c
@@ -320,17 +320,35 @@  int open_page_xfer(struct page_xfer *xfer, int fd_type, long id)
 		return open_page_local_xfer(xfer, fd_type, id);
 }
 
+static int dump_hole(struct page_xfer *xfer, struct page_pipe_iovs *iov,
+		     void *limit, unsigned long off)
+{
+	while (iov->busy_iov < iov->free_iov) {
+		struct iovec *hole = &iov->iovs[iov->busy_iov];
+
+		if (limit && hole->iov_base >= limit)
+			break;
+
+		BUG_ON(hole->iov_base < (void *)off);
+		hole->iov_base -= off;
+		pr_debug("\th %p [%u]\n", hole->iov_base,
+			 (unsigned int)(hole->iov_len / PAGE_SIZE));
+		if (xfer->write_hole(xfer, hole))
+			return -1;
+
+		iov->busy_iov++;
+	}
+
+	return 0;
+}
+
 int page_xfer_dump_pages(struct page_xfer *xfer, struct page_pipe *pp,
 		unsigned long off)
 {
 	struct page_pipe_buf *ppb;
-	struct iovec *hole = NULL;
 
 	pr_debug("Transfering pages:\n");
 
-	if (pp->holes.free_iov)
-		hole = &pp->holes.iovs[0];
-
 	list_for_each_entry(ppb, &pp->bufs, l) {
 		int i;
 
@@ -339,18 +357,8 @@  int page_xfer_dump_pages(struct page_xfer *xfer, struct page_pipe *pp,
 		for (i = 0; i < ppb->nr_segs; i++) {
 			struct iovec *iov = &ppb->iov[i];
 
-			while (hole && (hole->iov_base < iov->iov_base)) {
-				BUG_ON(hole->iov_base < (void *)off);
-				hole->iov_base -= off;
-				pr_debug("\th %p [%u]\n", hole->iov_base,
-						(unsigned int)(hole->iov_len / PAGE_SIZE));
-				if (xfer->write_hole(xfer, hole))
-					return -1;
-
-				hole++;
-				if (hole >= &pp->holes.iovs[pp->holes.free_iov])
-					hole = NULL;
-			}
+			if (dump_hole(xfer, &pp->holes, iov->iov_base, off))
+				return -1;
 
 			BUG_ON(iov->iov_base < (void *)off);
 			iov->iov_base -= off;
@@ -364,18 +372,8 @@  int page_xfer_dump_pages(struct page_xfer *xfer, struct page_pipe *pp,
 		}
 	}
 
-	while (hole) {
-		BUG_ON(hole->iov_base < (void *)off);
-		hole->iov_base -= off;
-		pr_debug("\th* %p [%u]\n", hole->iov_base,
-				(unsigned int)(hole->iov_len / PAGE_SIZE));
-		if (xfer->write_hole(xfer, hole))
-			return -1;
-
-		hole++;
-		if (hole >= &pp->holes.iovs[pp->holes.free_iov])
-			hole = NULL;
-	}
+	if (dump_hole(xfer, &pp->holes, NULL, off))
+		return -1;
 
 	return 0;
 }

Comments

Pavel Emelianov July 6, 2016, 7:56 a.m.
On 06/29/2016 08:55 AM, Mike Rapoport wrote:
> Signed-off-by: Mike Rapoport <rppt@linux.vnet.ibm.com>
> ---
>  criu/include/page-pipe.h |  1 +
>  criu/page-pipe.c         |  2 ++
>  criu/page-xfer.c         | 54 +++++++++++++++++++++++-------------------------
>  3 files changed, 29 insertions(+), 28 deletions(-)
> 
> diff --git a/criu/include/page-pipe.h b/criu/include/page-pipe.h
> index a018af0..f11071c 100644
> --- a/criu/include/page-pipe.h
> +++ b/criu/include/page-pipe.h
> @@ -83,6 +83,7 @@ struct page_pipe_buf {
>  struct page_pipe_iovs {
>  	unsigned int nr_iovs;	/* number of iovs */
>  	unsigned int free_iov;	/* number of iovs in use */
> +	unsigned int busy_iov;	/* first iov that not yet dumped */

Can we avoid having a member on page_pipe_iovs that is used in one
callstack only? And have a variable on the stack itself?

>  	struct iovec *iovs;	/* iovs */
>  };
>  
> diff --git a/criu/page-pipe.c b/criu/page-pipe.c
> index 9bc7eaf..d002c3a 100644
> --- a/criu/page-pipe.c
> +++ b/criu/page-pipe.c
> @@ -149,10 +149,12 @@ struct page_pipe *create_page_pipe(unsigned int nr_segs,
>  	pp->pages.nr_iovs = nr_segs;
>  	pp->pages.iovs = iovs;
>  	pp->pages.free_iov = 0;
> +	pp->pages.busy_iov = 0;
>  
>  	pp->holes.nr_iovs = 0;
>  	pp->holes.free_iov = 0;
>  	pp->holes.iovs = NULL;
> +	pp->holes.busy_iov = 0;
>  
>  	pp->chunk_mode = chunk_mode;
>  
> diff --git a/criu/page-xfer.c b/criu/page-xfer.c
> index 4bb8ea0..32b50f7 100644
> --- a/criu/page-xfer.c
> +++ b/criu/page-xfer.c
> @@ -320,17 +320,35 @@ int open_page_xfer(struct page_xfer *xfer, int fd_type, long id)
>  		return open_page_local_xfer(xfer, fd_type, id);
>  }
>  
> +static int dump_hole(struct page_xfer *xfer, struct page_pipe_iovs *iov,
> +		     void *limit, unsigned long off)
> +{
> +	while (iov->busy_iov < iov->free_iov) {
> +		struct iovec *hole = &iov->iovs[iov->busy_iov];
> +
> +		if (limit && hole->iov_base >= limit)
> +			break;
> +
> +		BUG_ON(hole->iov_base < (void *)off);
> +		hole->iov_base -= off;
> +		pr_debug("\th %p [%u]\n", hole->iov_base,
> +			 (unsigned int)(hole->iov_len / PAGE_SIZE));
> +		if (xfer->write_hole(xfer, hole))
> +			return -1;
> +
> +		iov->busy_iov++;
> +	}
> +
> +	return 0;
> +}
> +
>  int page_xfer_dump_pages(struct page_xfer *xfer, struct page_pipe *pp,
>  		unsigned long off)
>  {
>  	struct page_pipe_buf *ppb;
> -	struct iovec *hole = NULL;
>  
>  	pr_debug("Transfering pages:\n");
>  
> -	if (pp->holes.free_iov)
> -		hole = &pp->holes.iovs[0];
> -
>  	list_for_each_entry(ppb, &pp->bufs, l) {
>  		int i;
>  
> @@ -339,18 +357,8 @@ int page_xfer_dump_pages(struct page_xfer *xfer, struct page_pipe *pp,
>  		for (i = 0; i < ppb->nr_segs; i++) {
>  			struct iovec *iov = &ppb->iov[i];
>  
> -			while (hole && (hole->iov_base < iov->iov_base)) {
> -				BUG_ON(hole->iov_base < (void *)off);
> -				hole->iov_base -= off;
> -				pr_debug("\th %p [%u]\n", hole->iov_base,
> -						(unsigned int)(hole->iov_len / PAGE_SIZE));
> -				if (xfer->write_hole(xfer, hole))
> -					return -1;
> -
> -				hole++;
> -				if (hole >= &pp->holes.iovs[pp->holes.free_iov])
> -					hole = NULL;
> -			}
> +			if (dump_hole(xfer, &pp->holes, iov->iov_base, off))
> +				return -1;
>  
>  			BUG_ON(iov->iov_base < (void *)off);
>  			iov->iov_base -= off;
> @@ -364,18 +372,8 @@ int page_xfer_dump_pages(struct page_xfer *xfer, struct page_pipe *pp,
>  		}
>  	}
>  
> -	while (hole) {
> -		BUG_ON(hole->iov_base < (void *)off);
> -		hole->iov_base -= off;
> -		pr_debug("\th* %p [%u]\n", hole->iov_base,
> -				(unsigned int)(hole->iov_len / PAGE_SIZE));
> -		if (xfer->write_hole(xfer, hole))
> -			return -1;
> -
> -		hole++;
> -		if (hole >= &pp->holes.iovs[pp->holes.free_iov])
> -			hole = NULL;
> -	}
> +	if (dump_hole(xfer, &pp->holes, NULL, off))
> +		return -1;
>  
>  	return 0;
>  }
>
Pavel Emelianov July 6, 2016, 8:03 a.m.
Applied, thanks
Andrey Vagin July 6, 2016, 2:56 p.m.
Hi Mike,

It's for you;).

https://ci.openvz.org/job/CRIU/job/CRIU-snap/branch/criu-dev/501/consoleFull

======================== Run zdtm/transition/fork2 in h ========================
Start test
./fork2 --pidfile=fork2.pid --outfile=fork2.out
Adding page server
Run criu page-server
Run criu dump
Adding page server
Run criu page-server
Run criu dump
Adding page server
Run criu page-server
Run criu dump
=[log]=> dump/zdtm/transition/fork2/24/3/dump.log
------------------------ grep Error ------------------------
(00.063963) Error (page-xfer.c:138): The page server doesn't answer: Connection reset by peer
(00.064069) Error (mem.c:403): Can't dump page with parasite
(00.066249) Error (page-xfer.c:786): Can't write the fini command to server: Broken pipe
(00.066936) Error (cr-dump.c:1630): Dumping FAILED.
------------------------ ERROR OVER ------------------------
################# Test zdtm/transition/fork2 FAIL at CRIU dump #################

On Wed, Jun 29, 2016 at 08:55:09AM +0300, Mike Rapoport wrote:
> Signed-off-by: Mike Rapoport <rppt@linux.vnet.ibm.com>
> ---
>  criu/include/page-pipe.h |  1 +
>  criu/page-pipe.c         |  2 ++
>  criu/page-xfer.c         | 54 +++++++++++++++++++++++-------------------------
>  3 files changed, 29 insertions(+), 28 deletions(-)
> 
> diff --git a/criu/include/page-pipe.h b/criu/include/page-pipe.h
> index a018af0..f11071c 100644
> --- a/criu/include/page-pipe.h
> +++ b/criu/include/page-pipe.h
> @@ -83,6 +83,7 @@ struct page_pipe_buf {
>  struct page_pipe_iovs {
>  	unsigned int nr_iovs;	/* number of iovs */
>  	unsigned int free_iov;	/* number of iovs in use */
> +	unsigned int busy_iov;	/* first iov that not yet dumped */
>  	struct iovec *iovs;	/* iovs */
>  };
>  
> diff --git a/criu/page-pipe.c b/criu/page-pipe.c
> index 9bc7eaf..d002c3a 100644
> --- a/criu/page-pipe.c
> +++ b/criu/page-pipe.c
> @@ -149,10 +149,12 @@ struct page_pipe *create_page_pipe(unsigned int nr_segs,
>  	pp->pages.nr_iovs = nr_segs;
>  	pp->pages.iovs = iovs;
>  	pp->pages.free_iov = 0;
> +	pp->pages.busy_iov = 0;
>  
>  	pp->holes.nr_iovs = 0;
>  	pp->holes.free_iov = 0;
>  	pp->holes.iovs = NULL;
> +	pp->holes.busy_iov = 0;
>  
>  	pp->chunk_mode = chunk_mode;
>  
> diff --git a/criu/page-xfer.c b/criu/page-xfer.c
> index 4bb8ea0..32b50f7 100644
> --- a/criu/page-xfer.c
> +++ b/criu/page-xfer.c
> @@ -320,17 +320,35 @@ int open_page_xfer(struct page_xfer *xfer, int fd_type, long id)
>  		return open_page_local_xfer(xfer, fd_type, id);
>  }
>  
> +static int dump_hole(struct page_xfer *xfer, struct page_pipe_iovs *iov,
> +		     void *limit, unsigned long off)
> +{
> +	while (iov->busy_iov < iov->free_iov) {
> +		struct iovec *hole = &iov->iovs[iov->busy_iov];
> +
> +		if (limit && hole->iov_base >= limit)
> +			break;
> +
> +		BUG_ON(hole->iov_base < (void *)off);
> +		hole->iov_base -= off;
> +		pr_debug("\th %p [%u]\n", hole->iov_base,
> +			 (unsigned int)(hole->iov_len / PAGE_SIZE));
> +		if (xfer->write_hole(xfer, hole))
> +			return -1;
> +
> +		iov->busy_iov++;
> +	}
> +
> +	return 0;
> +}
> +
>  int page_xfer_dump_pages(struct page_xfer *xfer, struct page_pipe *pp,
>  		unsigned long off)
>  {
>  	struct page_pipe_buf *ppb;
> -	struct iovec *hole = NULL;
>  
>  	pr_debug("Transfering pages:\n");
>  
> -	if (pp->holes.free_iov)
> -		hole = &pp->holes.iovs[0];
> -
>  	list_for_each_entry(ppb, &pp->bufs, l) {
>  		int i;
>  
> @@ -339,18 +357,8 @@ int page_xfer_dump_pages(struct page_xfer *xfer, struct page_pipe *pp,
>  		for (i = 0; i < ppb->nr_segs; i++) {
>  			struct iovec *iov = &ppb->iov[i];
>  
> -			while (hole && (hole->iov_base < iov->iov_base)) {
> -				BUG_ON(hole->iov_base < (void *)off);
> -				hole->iov_base -= off;
> -				pr_debug("\th %p [%u]\n", hole->iov_base,
> -						(unsigned int)(hole->iov_len / PAGE_SIZE));
> -				if (xfer->write_hole(xfer, hole))
> -					return -1;
> -
> -				hole++;
> -				if (hole >= &pp->holes.iovs[pp->holes.free_iov])
> -					hole = NULL;
> -			}
> +			if (dump_hole(xfer, &pp->holes, iov->iov_base, off))
> +				return -1;
>  
>  			BUG_ON(iov->iov_base < (void *)off);
>  			iov->iov_base -= off;
> @@ -364,18 +372,8 @@ int page_xfer_dump_pages(struct page_xfer *xfer, struct page_pipe *pp,
>  		}
>  	}
>  
> -	while (hole) {
> -		BUG_ON(hole->iov_base < (void *)off);
> -		hole->iov_base -= off;
> -		pr_debug("\th* %p [%u]\n", hole->iov_base,
> -				(unsigned int)(hole->iov_len / PAGE_SIZE));
> -		if (xfer->write_hole(xfer, hole))
> -			return -1;
> -
> -		hole++;
> -		if (hole >= &pp->holes.iovs[pp->holes.free_iov])
> -			hole = NULL;
> -	}
> +	if (dump_hole(xfer, &pp->holes, NULL, off))
> +		return -1;
>  
>  	return 0;
>  }
> -- 
> 1.9.1
> 
> _______________________________________________
> CRIU mailing list
> CRIU@openvz.org
> https://lists.openvz.org/mailman/listinfo/criu