Commit b72d5f2d authored by Mike Rapoport's avatar Mike Rapoport Committed by Andrei Vagin

lazy-pages: extend the page_read with ability to read remote pages

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.

travis-ci: success for uffd: A new set of improvements
Signed-off-by: 's avatarMike Rapoport <rppt@linux.vnet.ibm.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
parent c23b83ce
......@@ -53,6 +53,8 @@ struct page_read {
int (*sync)(struct page_read *pr);
int (*seek_pagemap)(struct page_read *pr, unsigned long vaddr);
void (*reset)(struct page_read *pr);
int (*maybe_read_page)(struct page_read *pr, unsigned long vaddr,
int nr, void *buf, unsigned flags);
/* Whether or not pages can be read in PIE code */
bool pieok;
......@@ -72,7 +74,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 +93,7 @@ struct page_read {
#define PR_TYPE_MASK 0x3
#define PR_MOD 0x4 /* Will need to modify */
#define PR_REMOTE 0x8
/*
* -1 -- error
......
......@@ -12,6 +12,8 @@
#include "pagemap.h"
#include "restorer.h"
#include "rst-malloc.h"
#include "page-xfer.h"
#include "fault-injection.h"
#include "xmalloc.h"
#include "protobuf.h"
......@@ -393,8 +395,8 @@ int pagemap_enqueue_iovec(struct page_read *pr, void *buf,
return 0;
}
static int maybe_read_page(struct page_read *pr, unsigned long vaddr,
int nr, void *buf, unsigned flags)
static int maybe_read_page_local(struct page_read *pr, unsigned long vaddr,
int nr, void *buf, unsigned flags)
{
int ret;
unsigned long len = nr * PAGE_SIZE;
......@@ -409,6 +411,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,
int nr, void *buf, unsigned flags)
{
int ret;
if (flags & PR_ASYNC)
ret = -1; /* not yet supported */
else
ret = get_remote_pages(pr->pid, vaddr, nr, buf);
return ret;
}
static int read_pagemap_page(struct page_read *pr, unsigned long vaddr, int nr,
void *buf, unsigned flags)
{
......@@ -422,7 +437,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, nr, buf, flags) < 0)
if (pr->maybe_read_page(pr, vaddr, nr, buf, flags) < 0)
return -1;
}
......@@ -678,6 +693,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;
......@@ -741,11 +757,19 @@ int open_page_read_at(int dfd, int pid, struct page_read *pr, int pr_flags)
pr->seek_pagemap = seek_pagemap;
pr->reset = reset_pagemap;
pr->id = ids++;
if (!pr->parent)
pr->pieok = true;
pr->pid = pid;
if (remote)
pr->maybe_read_page = maybe_read_page_remote;
else {
pr->maybe_read_page = maybe_read_page_local;
if (!pr->parent && !opts.lazy_pages)
pr->pieok = true;
}
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;
}
......
......@@ -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;
......@@ -579,11 +582,7 @@ static int uffd_handle_pages(struct lazy_pages_info *lpi, __u64 address, int nr)
if (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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment