[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