[CRIU] [PATCH 6/7] page-read: Callback on io completion
Mike Rapoport
mike.rapoport at gmail.com
Wed Nov 16 02:55:53 PST 2016
On Wed, Nov 16, 2016 at 11:39 AM, Pavel Emelyanov <xemul at virtuozzo.com> wrote:
> This one is called by PR once IO is complete (right now
> for sync cases only, more work is required here) and
> lets us unify local and remote PF code in uffd.
>
> Signed-off-by: Pavel Emelyanov <xemul at virtuozzo.com>
> ---
Acked-by: Mike Rapoport <rppt at linux.vnet.ibm.com>
> criu/include/pagemap.h | 1 +
> criu/pagemap.c | 11 ++++++++++-
> criu/uffd.c | 19 ++++++++++++++-----
> 3 files changed, 25 insertions(+), 6 deletions(-)
>
> diff --git a/criu/include/pagemap.h b/criu/include/pagemap.h
> index fbe8ca0..50829ae 100644
> --- a/criu/include/pagemap.h
> +++ b/criu/include/pagemap.h
> @@ -58,6 +58,7 @@ struct page_read {
> void (*reset)(struct page_read *pr);
> int (*sync)(struct page_read *pr);
>
> + int (*io_complete)(struct page_read *, unsigned long vaddr, int nr);
> int (*maybe_read_page)(struct page_read *pr, unsigned long vaddr,
> int nr, void *buf, unsigned flags);
>
> diff --git a/criu/pagemap.c b/criu/pagemap.c
> index a9c37d7..f4439ec 100644
> --- a/criu/pagemap.c
> +++ b/criu/pagemap.c
> @@ -392,8 +392,11 @@ static int maybe_read_page_local(struct page_read *pr, unsigned long vaddr,
> */
> if ((flags & (PR_ASYNC|PR_ASAP)) == PR_ASYNC)
> ret = enqueue_async_page(pr, vaddr, len, buf);
> - else
> + else {
> ret = read_local_page(pr, vaddr, len, buf);
> + if (ret == 0 && pr->io_complete)
> + ret = pr->io_complete(pr, vaddr, nr);
> + }
>
> pr->pi_off += len;
>
> @@ -418,6 +421,9 @@ static int maybe_read_page_remote(struct page_read *pr, unsigned long vaddr,
> if (ret == 0)
> ret = receive_remote_pages(nr * PAGE_SIZE, buf);
>
> + if (ret == 0 && pr->io_complete)
> + ret = pr->io_complete(pr, vaddr, nr);
> +
> return ret;
> }
>
> @@ -471,6 +477,8 @@ static int process_async_reads(struct page_read *pr)
> if (opts.auto_dedup && punch_hole(pr, piov->from, ret, false))
> return -1;
>
> + BUG_ON(pr->io_complete); /* FIXME -- implement once needed */
> +
> list_del(&piov->l);
> xfree(piov->to);
> xfree(piov);
> @@ -700,6 +708,7 @@ int open_page_read_at(int dfd, int pid, struct page_read *pr, int pr_flags)
> pr->seek_page = seek_pagemap_page;
> pr->reset = reset_pagemap;
> pr->sync = process_async_reads;
> + pr->io_complete = NULL; /* set up by the client if needed */
> pr->id = ids++;
> pr->pid = pid;
>
> diff --git a/criu/uffd.c b/criu/uffd.c
> index 93cdee7..2464588 100644
> --- a/criu/uffd.c
> +++ b/criu/uffd.c
> @@ -476,6 +476,8 @@ free_mm:
> return ret;
> }
>
> +static int uffd_io_complete(struct page_read *pr, unsigned long vaddr, int nr);
> +
> static int ud_open(int client, struct lazy_pages_info **_lpi)
> {
> struct lazy_pages_info *lpi;
> @@ -523,6 +525,8 @@ static int ud_open(int client, struct lazy_pages_info **_lpi)
> goto out;
> }
>
> + lpi->pr.io_complete = uffd_io_complete;
> +
> /*
> * Find the memory pages belonging to the restored process
> * so that it is trackable when all pages have been transferred.
> @@ -587,6 +591,14 @@ static int complete_page_fault(struct lazy_pages_info *lpi, unsigned long vaddr,
> return update_lazy_iovecs(lpi, vaddr, nr * PAGE_SIZE);
> }
>
> +static int uffd_io_complete(struct page_read *pr, unsigned long vaddr, int nr)
> +{
> + struct lazy_pages_info *lpi;
> +
> + lpi = container_of(pr, struct lazy_pages_info, pr);
> + return complete_page_fault(lpi, vaddr, nr);
> +}
> +
> static int uffd_zero(struct lazy_pages_info *lpi, __u64 address, int nr_pages)
> {
> struct uffdio_zeropage uffdio_zeropage;
> @@ -655,7 +667,7 @@ static int uffd_handle_pages(struct lazy_pages_info *lpi, __u64 address, int nr)
> return ret;
> }
>
> - return complete_page_fault(lpi, address, nr);
> + return 0;
> }
>
> static int handle_remaining_pages(struct lazy_pages_info *lpi)
> @@ -700,10 +712,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, PR_ASYNC | PR_ASAP))
> - return -1;
> -
> - return complete_page_fault(lpi, address, nr);
> + return page_fault_common(lpi, address, nr, PR_ASYNC | PR_ASAP);
> }
>
> static int page_fault_remote(struct lazy_pages_info *lpi, __u64 address, int nr)
> --
> 2.5.0
>
--
Sincerely yours,
Mike.
More information about the CRIU
mailing list