Commit 1e78c91d authored by Pavel Emelyanov's avatar Pavel Emelyanov

page-xfer: Fix page writing API

Split it into two parts -- writing pagemap and writing
pages. This is required for page-server part, sinc it
cannot provide one big pipe with all the pages at once.
Thus it needs to feed pages in portions.
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent dcba1491
...@@ -9,8 +9,10 @@ int cr_page_server(void); ...@@ -9,8 +9,10 @@ int cr_page_server(void);
*/ */
struct page_xfer { struct page_xfer {
/* transfers one vaddr:len entry with pages */ /* transfers one vaddr:len entry */
int (*write_pagemap)(struct page_xfer *self, struct iovec *iov, int pipe); int (*write_pagemap)(struct page_xfer *self, struct iovec *iov);
/* transfers pages related to previous pagemap */
int (*write_pages)(struct page_xfer *self, int pipe, unsigned long len);
/* transfers one hole -- vaddr:len entry w/o pages */ /* transfers one hole -- vaddr:len entry w/o pages */
int (*write_hole)(struct page_xfer *self, struct iovec *iov); int (*write_hole)(struct page_xfer *self, struct iovec *iov);
void (*close)(struct page_xfer *self); void (*close)(struct page_xfer *self);
......
...@@ -216,7 +216,7 @@ int connect_to_page_server(void) ...@@ -216,7 +216,7 @@ int connect_to_page_server(void)
} }
static int write_pagemap_to_server(struct page_xfer *xfer, static int write_pagemap_to_server(struct page_xfer *xfer,
struct iovec *iov, int p) struct iovec *iov)
{ {
struct page_server_iov pi; struct page_server_iov pi;
...@@ -230,9 +230,15 @@ static int write_pagemap_to_server(struct page_xfer *xfer, ...@@ -230,9 +230,15 @@ static int write_pagemap_to_server(struct page_xfer *xfer,
return -1; return -1;
} }
pr_debug("Splicing %zu bytes / %u pages into socket\n", iov->iov_len, pi.nr_pages); return 0;
if (splice(p, NULL, xfer->fd, NULL, iov->iov_len, }
SPLICE_F_MOVE) != iov->iov_len) {
static int write_pages_to_server(struct page_xfer *xfer,
int p, unsigned long len)
{
pr_debug("Splicing %zu bytes / %zu pages into socket\n", len, len / PAGE_SIZE);
if (splice(p, NULL, xfer->fd, NULL, len, SPLICE_F_MOVE) != len) {
pr_perror("Can't write pages to socket"); pr_perror("Can't write pages to socket");
return -1; return -1;
} }
...@@ -255,6 +261,7 @@ int open_page_server_xfer(struct page_xfer *xfer, int fd_type, long id) ...@@ -255,6 +261,7 @@ int open_page_server_xfer(struct page_xfer *xfer, int fd_type, long id)
{ {
xfer->fd = page_server_sk; xfer->fd = page_server_sk;
xfer->write_pagemap = write_pagemap_to_server; xfer->write_pagemap = write_pagemap_to_server;
xfer->write_pages = write_pages_to_server;
xfer->write_hole = write_hole_to_server; xfer->write_hole = write_hole_to_server;
xfer->close = close_server_xfer; xfer->close = close_server_xfer;
xfer->dst_id = encode_pm_id(fd_type, id); xfer->dst_id = encode_pm_id(fd_type, id);
...@@ -263,18 +270,20 @@ int open_page_server_xfer(struct page_xfer *xfer, int fd_type, long id) ...@@ -263,18 +270,20 @@ int open_page_server_xfer(struct page_xfer *xfer, int fd_type, long id)
} }
static int write_pagemap_loc(struct page_xfer *xfer, static int write_pagemap_loc(struct page_xfer *xfer,
struct iovec *iov, int p) struct iovec *iov)
{ {
PagemapEntry pe = PAGEMAP_ENTRY__INIT; PagemapEntry pe = PAGEMAP_ENTRY__INIT;
pe.vaddr = encode_pointer(iov->iov_base); pe.vaddr = encode_pointer(iov->iov_base);
pe.nr_pages = iov->iov_len / PAGE_SIZE; pe.nr_pages = iov->iov_len / PAGE_SIZE;
if (pb_write_one(xfer->fd, &pe, PB_PAGEMAP) < 0) return pb_write_one(xfer->fd, &pe, PB_PAGEMAP);
return -1; }
if (splice(p, NULL, xfer->fd_pg, NULL, iov->iov_len, static int write_pages_loc(struct page_xfer *xfer,
SPLICE_F_MOVE) != iov->iov_len) int p, unsigned long len)
{
if (splice(p, NULL, xfer->fd_pg, NULL, len, SPLICE_F_MOVE) != len)
return -1; return -1;
return 0; return 0;
...@@ -334,7 +343,9 @@ int page_xfer_dump_pages(struct page_xfer *xfer, struct page_pipe *pp, ...@@ -334,7 +343,9 @@ int page_xfer_dump_pages(struct page_xfer *xfer, struct page_pipe *pp,
pr_debug("\t%p [%u]\n", iov->iov_base, pr_debug("\t%p [%u]\n", iov->iov_base,
(unsigned int)(iov->iov_len / PAGE_SIZE)); (unsigned int)(iov->iov_len / PAGE_SIZE));
if (xfer->write_pagemap(xfer, iov, ppb->p[0])) if (xfer->write_pagemap(xfer, iov))
return -1;
if (xfer->write_pages(xfer, ppb->p[0], iov->iov_len))
return -1; return -1;
} }
} }
...@@ -369,6 +380,7 @@ int open_page_xfer(struct page_xfer *xfer, int fd_type, long id) ...@@ -369,6 +380,7 @@ int open_page_xfer(struct page_xfer *xfer, int fd_type, long id)
} }
xfer->write_pagemap = write_pagemap_loc; xfer->write_pagemap = write_pagemap_loc;
xfer->write_pages = write_pages_loc;
xfer->write_hole = write_pagehole_loc; xfer->write_hole = write_pagehole_loc;
xfer->close = close_page_xfer; xfer->close = close_page_xfer;
return 0; return 0;
......
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