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

Submitted by Pavel Emelianov on Nov. 16, 2016, 9:39 a.m.

Details

Message ID 582C294A.7050008@virtuozzo.com
State Superseded
Commit 4efa05d4ddddceebb4c6ce92333fcbe25e27143c
Headers show

Commit Message

Pavel Emelianov Nov. 16, 2016, 9:39 a.m.
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@virtuozzo.com>
---
 criu/include/pagemap.h | 1 +
 criu/pagemap.c         | 9 ++++++++-
 criu/uffd.c            | 4 ++--
 3 files changed, 11 insertions(+), 3 deletions(-)

Patch hide | download patch | download mbox

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);

Comments

Mike Rapoport Nov. 16, 2016, 10:55 a.m.
On Wed, Nov 16, 2016 at 11:39 AM, Pavel Emelyanov <xemul@virtuozzo.com> wrote:
> 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.

A nitpeek below, otherwise

> Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
> ---

Acked-by: Mike Rapoport <rppt@linux.vnet.ibm.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 */

Why so many whitespace?

>  /* 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
>