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 { ...@@ -53,6 +53,8 @@ struct page_read {
int (*sync)(struct page_read *pr); int (*sync)(struct page_read *pr);
int (*seek_pagemap)(struct page_read *pr, unsigned long vaddr); int (*seek_pagemap)(struct page_read *pr, unsigned long vaddr);
void (*reset)(struct page_read *pr); 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 */ /* Whether or not pages can be read in PIE code */
bool pieok; bool pieok;
...@@ -72,7 +74,8 @@ struct page_read { ...@@ -72,7 +74,8 @@ struct page_read {
struct iovec bunch; /* record consequent neighbour struct iovec bunch; /* record consequent neighbour
iovecs to punch together */ iovecs to punch together */
unsigned id; /* for logging */ unsigned id; /* for logging */
int pid; /* PID of the process */
PagemapEntry **pmes; PagemapEntry **pmes;
int nr_pmes; int nr_pmes;
...@@ -90,6 +93,7 @@ struct page_read { ...@@ -90,6 +93,7 @@ struct page_read {
#define PR_TYPE_MASK 0x3 #define PR_TYPE_MASK 0x3
#define PR_MOD 0x4 /* Will need to modify */ #define PR_MOD 0x4 /* Will need to modify */
#define PR_REMOTE 0x8
/* /*
* -1 -- error * -1 -- error
......
...@@ -12,6 +12,8 @@ ...@@ -12,6 +12,8 @@
#include "pagemap.h" #include "pagemap.h"
#include "restorer.h" #include "restorer.h"
#include "rst-malloc.h" #include "rst-malloc.h"
#include "page-xfer.h"
#include "fault-injection.h" #include "fault-injection.h"
#include "xmalloc.h" #include "xmalloc.h"
#include "protobuf.h" #include "protobuf.h"
...@@ -393,8 +395,8 @@ int pagemap_enqueue_iovec(struct page_read *pr, void *buf, ...@@ -393,8 +395,8 @@ int pagemap_enqueue_iovec(struct page_read *pr, void *buf,
return 0; return 0;
} }
static int maybe_read_page(struct page_read *pr, unsigned long vaddr, static int maybe_read_page_local(struct page_read *pr, unsigned long vaddr,
int nr, void *buf, unsigned flags) int nr, void *buf, unsigned flags)
{ {
int ret; int ret;
unsigned long len = nr * PAGE_SIZE; unsigned long len = nr * PAGE_SIZE;
...@@ -409,6 +411,19 @@ static int maybe_read_page(struct page_read *pr, unsigned long vaddr, ...@@ -409,6 +411,19 @@ static int maybe_read_page(struct page_read *pr, unsigned long vaddr,
return ret; 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, static int read_pagemap_page(struct page_read *pr, unsigned long vaddr, int nr,
void *buf, unsigned flags) void *buf, unsigned flags)
{ {
...@@ -422,7 +437,7 @@ static int read_pagemap_page(struct page_read *pr, unsigned long vaddr, int nr, ...@@ -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 */ /* zero mappings should be skipped by get_pagemap */
BUG(); BUG();
} else { } else {
if (maybe_read_page(pr, vaddr, nr, buf, flags) < 0) if (pr->maybe_read_page(pr, vaddr, nr, buf, flags) < 0)
return -1; return -1;
} }
...@@ -678,6 +693,7 @@ int open_page_read_at(int dfd, int pid, struct page_read *pr, int pr_flags) ...@@ -678,6 +693,7 @@ int open_page_read_at(int dfd, int pid, struct page_read *pr, int pr_flags)
{ {
int flags, i_typ; int flags, i_typ;
static unsigned ids = 1; static unsigned ids = 1;
bool remote = pr_flags & PR_REMOTE;
if (opts.auto_dedup) if (opts.auto_dedup)
pr_flags |= PR_MOD; pr_flags |= PR_MOD;
...@@ -741,11 +757,19 @@ int open_page_read_at(int dfd, int pid, struct page_read *pr, int pr_flags) ...@@ -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->seek_pagemap = seek_pagemap;
pr->reset = reset_pagemap; pr->reset = reset_pagemap;
pr->id = ids++; pr->id = ids++;
if (!pr->parent) pr->pid = pid;
pr->pieok = true;
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_debug("Opened %s page read %u (parent %u)\n",
pr->id, pr->parent ? pr->parent->id : 0); remote ? "remote" : "local", pr->id,
pr->parent ? pr->parent->id : 0);
return 1; return 1;
} }
......
...@@ -452,6 +452,7 @@ static int ud_open(int client, struct lazy_pages_info **_lpi) ...@@ -452,6 +452,7 @@ static int ud_open(int client, struct lazy_pages_info **_lpi)
struct lazy_pages_info *lpi; struct lazy_pages_info *lpi;
int ret = -1; int ret = -1;
int uffd_flags; int uffd_flags;
int pr_flags = PR_TASK;
lpi = lpi_init(); lpi = lpi_init();
if (!lpi) if (!lpi)
...@@ -485,7 +486,9 @@ static int ud_open(int client, struct lazy_pages_info **_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); uffd_flags = fcntl(lpi->lpfd.fd, F_GETFD, NULL);
pr_debug("uffd_flags are 0x%x\n", uffd_flags); 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) { if (ret <= 0) {
ret = -1; ret = -1;
goto out; goto out;
...@@ -579,11 +582,7 @@ static int uffd_handle_pages(struct lazy_pages_info *lpi, __u64 address, int nr) ...@@ -579,11 +582,7 @@ static int uffd_handle_pages(struct lazy_pages_info *lpi, __u64 address, int nr)
if (pagemap_zero(lpi->pr.pe)) if (pagemap_zero(lpi->pr.pe))
return uffd_zero(lpi, address, nr); return uffd_zero(lpi, address, nr);
if (opts.use_page_server) ret = lpi->pr.read_pages(&lpi->pr, address, nr, lpi->buf, 0);
ret = get_remote_pages(lpi->pid, address, nr, lpi->buf);
else
ret = lpi->pr.read_pages(&lpi->pr, address, nr, lpi->buf, 0);
if (ret <= 0) { if (ret <= 0) {
pr_err("%d: failed reading pages at %llx\n", lpi->pid, address); pr_err("%d: failed reading pages at %llx\n", lpi->pid, address);
return ret; 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