[CRIU] [PATCH v3 2/3] page-read: Add async arg to ->read_pages callback

Mike Rapoport rppt at linux.vnet.ibm.com
Sat Nov 12 23:27:50 PST 2016


From: Pavel Emelyanov <xemul at virtuozzo.com>

Flag PR_ASYNC means, that the caller is OK if the routine
returns w/o data read into the buffer provided.

Signed-off-by: Pavel Emelyanov <xemul at virtuozzo.com>
Signed-off-by: Mike Rapoport <rppt at linux.vnet.ibm.com>
---
 criu/include/pagemap.h |  7 ++++++-
 criu/mem.c             |  4 ++--
 criu/pagemap.c         | 13 +++++++------
 criu/shmem.c           |  2 +-
 criu/uffd.c            |  2 +-
 5 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/criu/include/pagemap.h b/criu/include/pagemap.h
index 53b5375..af0dca0 100644
--- a/criu/include/pagemap.h
+++ b/criu/include/pagemap.h
@@ -47,7 +47,8 @@ struct page_read {
 	 */
 	int (*get_pagemap)(struct page_read *, struct iovec *iov);
 	/* reads page from current pagemap */
-	int (*read_pages)(struct page_read *, unsigned long vaddr, int nr, void *);
+	int (*read_pages)(struct page_read *, unsigned long vaddr, int nr,
+			  void *, unsigned flags);
 	void (*close)(struct page_read *);
 	void (*skip_pages)(struct page_read *, unsigned long len);
 	int (*seek_page)(struct page_read *pr, unsigned long vaddr, bool warn);
@@ -76,6 +77,10 @@ struct page_read {
 	int curr_pme;
 };
 
+/* flags for ->read_pages */
+#define PR_ASYNC	0x1 /* may exit w/o data in the buffer */
+
+/* flags for open_page_read */
 #define PR_SHMEM	0x1
 #define PR_TASK		0x2
 
diff --git a/criu/mem.c b/criu/mem.c
index 10cc197..86d2016 100644
--- a/criu/mem.c
+++ b/criu/mem.c
@@ -791,7 +791,7 @@ static int restore_priv_vma_content(struct pstree_item *t)
 			if (vma->ppage_bitmap) { /* inherited vma */
 				clear_bit(off, vma->ppage_bitmap);
 
-				ret = pr.read_pages(&pr, va, 1, buf);
+				ret = pr.read_pages(&pr, va, 1, buf, 0);
 				if (ret < 0)
 					goto err_read;
 
@@ -819,7 +819,7 @@ static int restore_priv_vma_content(struct pstree_item *t)
 
 				nr = min_t(int, nr_pages - i, (vma->e->end - va) / PAGE_SIZE);
 
-				ret = pr.read_pages(&pr, va, nr, p);
+				ret = pr.read_pages(&pr, va, nr, p, PR_ASYNC);
 				if (ret < 0)
 					goto err_read;
 
diff --git a/criu/pagemap.c b/criu/pagemap.c
index 69dc9ab..ea5ae19 100644
--- a/criu/pagemap.c
+++ b/criu/pagemap.c
@@ -207,7 +207,7 @@ static inline void pagemap_bound_check(PagemapEntry *pe, unsigned long vaddr, in
 }
 
 static int read_parent_page(struct page_read *pr, unsigned long vaddr,
-			    int nr, void *buf)
+			    int nr, void *buf, unsigned flags)
 {
 	struct page_read *ppr = pr->parent;
 	int ret;
@@ -238,7 +238,7 @@ static int read_parent_page(struct page_read *pr, unsigned long vaddr,
 		if (p_nr > nr)
 			p_nr = nr;
 
-		ret = ppr->read_pages(ppr, vaddr, p_nr, buf);
+		ret = ppr->read_pages(ppr, vaddr, p_nr, buf, flags);
 		if (ret == -1)
 			return ret;
 
@@ -256,7 +256,7 @@ static int read_parent_page(struct page_read *pr, unsigned long vaddr,
 }
 
 static int read_local_page(struct page_read *pr, unsigned long vaddr,
-			   unsigned long len, void *buf)
+			   unsigned long len, void *buf, unsigned flags)
 {
 	int fd = img_raw_fd(pr->pi);
 	int ret;
@@ -284,7 +284,8 @@ static int read_local_page(struct page_read *pr, unsigned long vaddr,
 	return 0;
 }
 
-static int read_pagemap_page(struct page_read *pr, unsigned long vaddr, int nr, void *buf)
+static int read_pagemap_page(struct page_read *pr, unsigned long vaddr, int nr,
+			     void *buf, unsigned flags)
 {
 	unsigned long len = nr * PAGE_SIZE;
 
@@ -292,13 +293,13 @@ static int read_pagemap_page(struct page_read *pr, unsigned long vaddr, int nr,
 	pagemap_bound_check(pr->pe, vaddr, nr);
 
 	if (pagemap_in_parent(pr->pe)) {
-		if (read_parent_page(pr, vaddr, nr, buf) < 0)
+		if (read_parent_page(pr, vaddr, nr, buf, flags) < 0)
 			return -1;
 	} else if (pagemap_zero(pr->pe)) {
 		/* zero mappings should be skipped by get_pagemap */
 		BUG();
 	} else {
-		if (read_local_page(pr, vaddr, len, buf) < 0)
+		if (read_local_page(pr, vaddr, len, buf, flags) < 0)
 			return -1;
 	}
 
diff --git a/criu/shmem.c b/criu/shmem.c
index 95c2d2e..d0a284c 100644
--- a/criu/shmem.c
+++ b/criu/shmem.c
@@ -482,7 +482,7 @@ static int restore_shmem_content(void *addr, struct shmem_info *si)
 		if (vaddr + nr_pages * PAGE_SIZE > si->size)
 			break;
 
-		pr.read_pages(&pr, vaddr, nr_pages, addr + vaddr);
+		pr.read_pages(&pr, vaddr, nr_pages, addr + vaddr, 0);
 	}
 
 	pr.close(&pr);
diff --git a/criu/uffd.c b/criu/uffd.c
index 8d5e633..9998257 100644
--- a/criu/uffd.c
+++ b/criu/uffd.c
@@ -392,7 +392,7 @@ static int get_page(struct lazy_pages_info *lpi, unsigned long addr, void *dest)
 	if (pagemap_zero(lpi->pr.pe))
 		return 0;
 
-	ret = lpi->pr.read_pages(&lpi->pr, addr, 1, buf);
+	ret = lpi->pr.read_pages(&lpi->pr, addr, 1, buf, 0);
 	pr_debug("read_pages ret %d\n", ret);
 	if (ret <= 0)
 		return ret;
-- 
1.9.1



More information about the CRIU mailing list