[CRIU] [PATCH 3/3] uffd: add handling of zero pages

Mike Rapoport rppt at linux.vnet.ibm.com
Thu Mar 31 04:39:21 PDT 2016


When get_page returns 0, it means that a page is mapped by a vma but it is
not found in the pagemap. This happens when a page is a zero page and
threofre skipped by dump.
Use UFFDIO_ZEROMAP to create a zero page in the restored process address
space.

Signed-off-by: Mike Rapoport <rppt at linux.vnet.ibm.com>
---
 criu/uffd.c | 32 ++++++++++++++++++++++++++++++--
 1 file changed, 30 insertions(+), 2 deletions(-)

diff --git a/criu/uffd.c b/criu/uffd.c
index 425b1d4..03c4b71 100644
--- a/criu/uffd.c
+++ b/criu/uffd.c
@@ -251,7 +251,7 @@ static int uffd_copy_page(int uffd, __u64 address, void *dest)
 
 	rc = get_page(address, dest);
 	if (rc <= 0)
-		return -1;
+		return rc;
 
 	uffdio_copy.dst = address;
 	uffdio_copy.src = (unsigned long) dest;
@@ -280,9 +280,37 @@ static int uffd_copy_page(int uffd, __u64 address, void *dest)
 
 }
 
+static int uffd_zero_page(int uffd, __u64 address)
+{
+	struct uffdio_zeropage uffdio_zeropage;
+	unsigned long ps = page_size();
+	int rc;
+
+	uffdio_zeropage.range.start = address;
+	uffdio_zeropage.range.len = ps;
+	uffdio_zeropage.mode = 0;
+
+	pr_debug("uffdio_zeropage.range.start 0x%llx\n", uffdio_zeropage.range.start);
+	rc = ioctl(uffd, UFFDIO_ZEROPAGE, &uffdio_zeropage);
+	pr_debug("ioctl UFFDIO_ZEROPAGE rc 0x%x\n", rc);
+	pr_debug("uffdio_zeropage.zeropage 0x%llx\n", uffdio_zeropage.zeropage);
+	if (rc) {
+		pr_err("UFFDIO_ZEROPAGE error %d\n", rc);
+		return -1;
+	}
+
+	return ps;
+}
+
 static int uffd_handle_page(int uffd, __u64 address, void *dest)
 {
-	return uffd_copy_page(uffd, address, dest);
+	int rc;
+
+	rc = uffd_copy_page(uffd, address, dest);
+	if (rc == 0)
+		rc = uffd_zero_page(uffd, address);
+
+	return rc;
 }
 
 static int collect_uffd_pages(struct page_read *pr, struct list_head *uffd_list)
-- 
1.9.1



More information about the CRIU mailing list