[CRIU] [PATCH 1/3] page-read: Add skip_zero argument to ->advance method

Pavel Emelyanov xemul at virtuozzo.com
Wed Nov 30 02:47:38 PST 2016


And optimize the get_pagemap() caller to reuse this.

Signed-off-by: Pavel Emelyanov <xemul at virtuozzo.com>
---
 criu/include/pagemap.h |  4 ++--
 criu/page-xfer.c       |  4 ++--
 criu/pagemap.c         | 29 ++++++++++++-----------------
 criu/uffd.c            |  2 +-
 4 files changed, 17 insertions(+), 22 deletions(-)

diff --git a/criu/include/pagemap.h b/criu/include/pagemap.h
index ea106ec..6f41ebc 100644
--- a/criu/include/pagemap.h
+++ b/criu/include/pagemap.h
@@ -50,8 +50,8 @@ struct page_read {
 	/* reads page from current pagemap */
 	int (*read_pages)(struct page_read *, unsigned long vaddr, int nr,
 			  void *, unsigned flags);
-	/* Advance page_read to the next entry (including zero pagemaps) */
-	int (*advance)(struct page_read *pr);
+	/* Advance page_read to the next entry */
+	int (*advance)(struct page_read *pr, bool skip_zero);
 	void (*close)(struct page_read *);
 	void (*skip_pages)(struct page_read *, unsigned long len);
 	int (*seek_pagemap)(struct page_read *pr, unsigned long vaddr,
diff --git a/criu/page-xfer.c b/criu/page-xfer.c
index 315d152..b60863a 100644
--- a/criu/page-xfer.c
+++ b/criu/page-xfer.c
@@ -823,7 +823,7 @@ static int fill_page_pipe(struct page_read *pr, struct page_pipe *pp)
 
 	pr->reset(pr);
 
-	while (pr->advance(pr)) {
+	while (pr->advance(pr, false)) {
 		unsigned long vaddr = pr->pe->vaddr;
 
 		for (i = 0; i < pr->pe->nr_pages; i++, vaddr += PAGE_SIZE) {
@@ -867,7 +867,7 @@ static int page_pipe_from_pagemap(struct page_pipe **pp, int pid)
 		return -1;
 	}
 
-	while (pr.advance(&pr))
+	while (pr.advance(&pr, false))
 		if (pagemap_present(pr.pe))
 			nr_pages += pr.pe->nr_pages;
 
diff --git a/criu/pagemap.c b/criu/pagemap.c
index a165a43..5ba4c3f 100644
--- a/criu/pagemap.c
+++ b/criu/pagemap.c
@@ -138,26 +138,24 @@ int dedup_one_iovec(struct page_read *pr, struct iovec *iov)
 	return 0;
 }
 
-static int advance(struct page_read *pr)
+static int advance(struct page_read *pr, bool skip_zero)
 {
-	pr->curr_pme++;
-	if (pr->curr_pme >= pr->nr_pmes)
-		return 0;
+	do {
+		pr->curr_pme++;
+		if (pr->curr_pme >= pr->nr_pmes)
+			return 0;
 
-	pr->pe = pr->pmes[pr->curr_pme];
-	pr->cvaddr = pr->pe->vaddr;
+		pr->pe = pr->pmes[pr->curr_pme];
+		pr->cvaddr = pr->pe->vaddr;
+	} while (skip_zero && pagemap_zero(pr->pe));
 
 	return 1;
 }
 
 static int get_pagemap(struct page_read *pr, struct iovec *iov)
 {
-	for (;;) {
-		if (!advance(pr))
-			return 0;
-		if (!pagemap_zero(pr->pe))
-			break;
-	}
+	if (!advance(pr, true))
+		return 0;
 
 	if (pagemap_in_parent(pr->pe) && !pr->parent) {
 		pr_err("No parent for snapshot pagemap\n");
@@ -183,16 +181,13 @@ static int seek_pagemap(struct page_read *pr, unsigned long vaddr,
 			bool skip_zero)
 {
 	if (!pr->pe)
-		advance(pr);
+		advance(pr, skip_zero);
 
 	do {
 		unsigned long start = pr->pe->vaddr;
 		unsigned long len = pr->pe->nr_pages * PAGE_SIZE;
 		unsigned long end = start + len;
 
-		if (skip_zero && pagemap_zero(pr->pe))
-			continue;
-
 		if (vaddr < pr->cvaddr)
 			break;
 
@@ -203,7 +198,7 @@ static int seek_pagemap(struct page_read *pr, unsigned long vaddr,
 
 		if (end <= vaddr)
 			skip_pagemap_pages(pr, end - pr->cvaddr);
-	} while (advance(pr));
+	} while (advance(pr, skip_zero));
 
 	return 0;
 }
diff --git a/criu/uffd.c b/criu/uffd.c
index b7bffc1..8eaf886 100644
--- a/criu/uffd.c
+++ b/criu/uffd.c
@@ -397,7 +397,7 @@ static int collect_lazy_iovecs(struct lazy_pages_info *lpi)
 	if (!mm)
 		return -1;
 
-	while (pr->advance(pr)) {
+	while (pr->advance(pr, false)) {
 		if (!pagemap_lazy(pr->pe))
 			continue;
 
-- 
2.5.0



More information about the CRIU mailing list