[CRIU] [PATCH 4/7] page-read: Introduce PR_ASAP flag for read_pages

Pavel Emelyanov xemul at virtuozzo.com
Wed Nov 16 01:39:22 PST 2016


This flag means, that the PR_ASYNC is valid, but the IO
should be started ASAP. This is how remote reader works,
so this flag is mostly for the local reader. It will let
us unify page-fault handlers for local and remote cases.

Signed-off-by: Pavel Emelyanov <xemul at virtuozzo.com>
---
 criu/include/pagemap.h | 1 +
 criu/pagemap.c         | 9 ++++++++-
 criu/uffd.c            | 4 ++--
 3 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/criu/include/pagemap.h b/criu/include/pagemap.h
index 98ad7ae..fbe8ca0 100644
--- a/criu/include/pagemap.h
+++ b/criu/include/pagemap.h
@@ -87,6 +87,7 @@ struct page_read {
 
 /* flags for ->read_pages */
 #define PR_ASYNC	0x1 /* may exit w/o data in the buffer */
+#define PR_ASAP		0x2 /* PR_ASYNC, but start the IO right now */
 
 /* flags for open_page_read */
 #define PR_SHMEM	0x1
diff --git a/criu/pagemap.c b/criu/pagemap.c
index 86791d7..a9c37d7 100644
--- a/criu/pagemap.c
+++ b/criu/pagemap.c
@@ -384,7 +384,13 @@ static int maybe_read_page_local(struct page_read *pr, unsigned long vaddr,
 	int ret;
 	unsigned long len = nr * PAGE_SIZE;
 
-	if (flags & PR_ASYNC)
+	/*
+	 * There's no API in the kernel to start asynchronous
+	 * cached read (or write), so in case someone is asking
+	 * for us for urgent async read, just do the regular
+	 * cached read.
+	 */
+	if ((flags & (PR_ASYNC|PR_ASAP)) == PR_ASYNC)
 		ret = enqueue_async_page(pr, vaddr, len, buf);
 	else
 		ret = read_local_page(pr, vaddr, len, buf);
@@ -399,6 +405,7 @@ static int maybe_read_page_remote(struct page_read *pr, unsigned long vaddr,
 {
 	int ret, pid;
 
+	/* We always do PR_ASAP mode here (FIXME?) */
 	ret = request_remote_pages(pr->pid, vaddr, nr);
 	if ((ret < 0) || (flags & PR_ASYNC))
 		return ret;
diff --git a/criu/uffd.c b/criu/uffd.c
index 7efccf5..46ac9f2 100644
--- a/criu/uffd.c
+++ b/criu/uffd.c
@@ -686,7 +686,7 @@ static int page_fault_common(struct lazy_pages_info *lpi, __u64 address, int nr,
 
 static int page_fault_local(struct lazy_pages_info *lpi, __u64 address, int nr)
 {
-	if (page_fault_common(lpi, address, nr, 0))
+	if (page_fault_common(lpi, address, nr, PR_ASYNC | PR_ASAP))
 		return -1;
 
 	if (uffd_copy(lpi, address, nr))
@@ -700,7 +700,7 @@ static int page_fault_local(struct lazy_pages_info *lpi, __u64 address, int nr)
 
 static int page_fault_remote(struct lazy_pages_info *lpi, __u64 address, int nr)
 {
-	return page_fault_common(lpi, address, nr, PR_ASYNC);
+	return page_fault_common(lpi, address, nr, PR_ASYNC | PR_ASAP);
 }
 
 static int (*pf_handler)(struct lazy_pages_info *lpi, __u64 address, int nr);
-- 
2.5.0



More information about the CRIU mailing list