[CRIU] [RFC PATCH 1/7] lazy-pages: extend the page_read with ability to read remote pages

Mike Rapoport mike.rapoport at gmail.com
Tue Nov 15 07:38:23 PST 2016


On Tue, Nov 15, 2016 at 5:40 PM, Pavel Emelyanov <xemul at virtuozzo.com> wrote:
> On 11/14/2016 06:37 PM, Mike Rapoport wrote:
>> Currently lazy-pages daemon uses either pr->read_pages or get_remote_pages
>> to get actual page data from local images or remote server. From now on,
>> page_read will be completely responsible for getting the page data.
>>
>> Signed-off-by: Mike Rapoport <rppt at linux.vnet.ibm.com>
>> ---
>>  criu/include/pagemap.h |  7 ++++++-
>>  criu/pagemap.c         | 32 +++++++++++++++++++++++++++-----
>>  criu/uffd.c            | 11 +++++------
>>  3 files changed, 38 insertions(+), 12 deletions(-)
>>
>> diff --git a/criu/include/pagemap.h b/criu/include/pagemap.h
>> index 711e169..e4a4ecd 100644
>> --- a/criu/include/pagemap.h
>> +++ b/criu/include/pagemap.h
>> @@ -58,6 +58,9 @@ struct page_read {
>>       void (*reset)(struct page_read *pr);
>>       int (*sync)(struct page_read *pr);
>>
>> +     int (*maybe_read_page)(struct page_read *pr, unsigned long vaddr,
>> +                            unsigned long len, void *buf, unsigned flags);
>> +
>>       /* Private data of reader */
>>       struct cr_img *pmi;
>>       struct cr_img *pi;
>> @@ -72,7 +75,8 @@ struct page_read {
>>
>>       struct iovec bunch;             /* record consequent neighbour
>>                                          iovecs to punch together */
>> -     unsigned id; /* for logging */
>> +     unsigned id;                    /* for logging */
>> +     int pid;                        /* PID of the process */
>>
>>       PagemapEntry **pmes;
>>       int nr_pmes;
>> @@ -90,6 +94,7 @@ struct page_read {
>>
>>  #define PR_TYPE_MASK 0x3
>>  #define PR_MOD               0x4     /* Will need to modify */
>> +#define PR_REMOTE    0x8
>>
>>  /*
>>   * -1 -- error
>> diff --git a/criu/pagemap.c b/criu/pagemap.c
>> index 1112515..728b031 100644
>> --- a/criu/pagemap.c
>> +++ b/criu/pagemap.c
>> @@ -10,6 +10,7 @@
>>  #include "cr_options.h"
>>  #include "servicefd.h"
>>  #include "pagemap.h"
>> +#include "page-xfer.h"
>>
>>  #include "xmalloc.h"
>>  #include "protobuf.h"
>> @@ -377,8 +378,8 @@ static int enqueue_async_page(struct page_read *pr, unsigned long vaddr,
>>       return 0;
>>  }
>>
>> -static int maybe_read_page(struct page_read *pr, unsigned long vaddr,
>> -                        unsigned long len, void *buf, unsigned flags)
>> +static int maybe_read_page_local(struct page_read *pr, unsigned long vaddr,
>> +                              unsigned long len, void *buf, unsigned flags)
>>  {
>>       int ret;
>>
>> @@ -392,6 +393,19 @@ static int maybe_read_page(struct page_read *pr, unsigned long vaddr,
>>       return ret;
>>  }
>>
>> +static int maybe_read_page_remote(struct page_read *pr, unsigned long vaddr,
>> +                               unsigned long len, void *buf, unsigned flags)
>> +{
>> +     int ret;
>> +
>> +     if (flags & PR_ASYNC)
>> +             ret = -1;       /* not yet supported */
>> +     else
>> +             ret = get_remote_pages(pr->pid, vaddr, len / PAGE_SIZE, buf);
>> +
>> +     return ret;
>> +}
>> +
>>  static int read_pagemap_page(struct page_read *pr, unsigned long vaddr, int nr,
>>                            void *buf, unsigned flags)
>>  {
>> @@ -407,7 +421,7 @@ static int read_pagemap_page(struct page_read *pr, unsigned long vaddr, int nr,
>>               /* zero mappings should be skipped by get_pagemap */
>>               BUG();
>>       } else {
>> -             if (maybe_read_page(pr, vaddr, len, buf, flags) < 0)
>> +             if (pr->maybe_read_page(pr, vaddr, len, buf, flags) < 0)
>>                       return -1;
>>       }
>>
>> @@ -605,6 +619,7 @@ int open_page_read_at(int dfd, int pid, struct page_read *pr, int pr_flags)
>>  {
>>       int flags, i_typ;
>>       static unsigned ids = 1;
>> +     bool remote = pr_flags & PR_REMOTE;
>>
>>       if (opts.auto_dedup)
>>               pr_flags |= PR_MOD;
>> @@ -668,9 +683,16 @@ int open_page_read_at(int dfd, int pid, struct page_read *pr, int pr_flags)
>
> Here between these lines we have call to try_open_parent(), but parent
> page_read-s are always local, so the PR_REMOTE flag should (probably)
> be dropped. Should it?

Yes, until we implement PR_REMOTE_PARENT :)

>>       pr->reset = reset_pagemap;
>>       pr->sync = process_async_reads;
>>       pr->id = ids++;
>> +     pr->pid = pid;
>> +
>> +     if (remote)
>> +             pr->maybe_read_page = maybe_read_page_remote;
>> +     else
>> +             pr->maybe_read_page = maybe_read_page_local;
>>
>> -     pr_debug("Opened page read %u (parent %u)\n",
>> -                     pr->id, pr->parent ? pr->parent->id : 0);
>> +     pr_debug("Opened %s page read %u (parent %u)\n",
>> +              remote ? "remote" : "local", pr->id,
>> +              pr->parent ? pr->parent->id : 0);
>>
>>       return 1;
>>  }
>> diff --git a/criu/uffd.c b/criu/uffd.c
>> index 06857fd..3eddf85 100644
>> --- a/criu/uffd.c
>> +++ b/criu/uffd.c
>> @@ -452,6 +452,7 @@ static int ud_open(int client, struct lazy_pages_info **_lpi)
>>       struct lazy_pages_info *lpi;
>>       int ret = -1;
>>       int uffd_flags;
>> +     int pr_flags = PR_TASK;
>>
>>       lpi = lpi_init();
>>       if (!lpi)
>> @@ -485,7 +486,9 @@ static int ud_open(int client, struct lazy_pages_info **_lpi)
>>       uffd_flags = fcntl(lpi->lpfd.fd, F_GETFD, NULL);
>>       pr_debug("uffd_flags are 0x%x\n", uffd_flags);
>>
>> -     ret = open_page_read(lpi->pid, &lpi->pr, PR_TASK);
>> +     if (opts.use_page_server)
>> +             pr_flags |= PR_REMOTE;
>> +     ret = open_page_read(lpi->pid, &lpi->pr, pr_flags);
>>       if (ret <= 0) {
>>               ret = -1;
>>               goto out;
>> @@ -584,11 +587,7 @@ static int uffd_handle_pages(struct lazy_pages_info *lpi, __u64 address, int nr)
>>       if (ret == 0 || pagemap_zero(lpi->pr.pe))
>>               return uffd_zero(lpi, address, nr);
>>
>> -     if (opts.use_page_server)
>> -             ret = get_remote_pages(lpi->pid, address, nr, lpi->buf);
>> -     else
>> -             ret = lpi->pr.read_pages(&lpi->pr, address, nr, lpi->buf, 0);
>> -
>> +     ret = lpi->pr.read_pages(&lpi->pr, address, nr, lpi->buf, 0);
>>       if (ret <= 0) {
>>               pr_err("%d: failed reading pages at %llx\n", lpi->pid, address);
>>               return ret;
>>
>
> _______________________________________________
> CRIU mailing list
> CRIU at openvz.org
> https://lists.openvz.org/mailman/listinfo/criu



-- 
Sincerely yours,
Mike.


More information about the CRIU mailing list