From 121f07a79f73a1ed0e5faa497073e1886ef1a894 Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Thu, 6 Jul 2017 12:40:56 +0300 Subject: [PATCH] page-xfer: Move iov offset on xfer The offset in question is used by shmem dumping code to dump memory segments relative to shmem segment start, no to task mapping start. The offset value is now the part of the xfer callback and is typically 0 :) Let's keep this on xfer object to simplify the xfer API. Acked-by: Mike Rapoport Signed-off-by: Pavel Emelyanov Signed-off-by: Andrei Vagin --- criu/cr-dump.c | 2 +- criu/include/page-xfer.h | 9 +++++++-- criu/mem.c | 2 +- criu/page-xfer.c | 22 ++++++++++++---------- criu/shmem.c | 10 ++++++---- 5 files changed, 27 insertions(+), 18 deletions(-) diff --git a/criu/cr-dump.c b/criu/cr-dump.c index 0e297acb7..cf0ac8093 100644 --- a/criu/cr-dump.c +++ b/criu/cr-dump.c @@ -1491,7 +1491,7 @@ static int cr_pre_dump_finish(int ret) goto err; mem_pp = dmpi(item)->mem_pp; - ret = page_xfer_dump_pages(&xfer, mem_pp, 0, true); + ret = page_xfer_dump_pages(&xfer, mem_pp, true); xfer.close(&xfer); diff --git a/criu/include/page-xfer.h b/criu/include/page-xfer.h index 2b806c797..00b18d3b4 100644 --- a/criu/include/page-xfer.h +++ b/criu/include/page-xfer.h @@ -17,6 +17,12 @@ struct page_xfer { int (*write_pages)(struct page_xfer *self, int pipe, unsigned long len); void (*close)(struct page_xfer *self); + /* + * In case we need to dump pagemaps not as-is, but + * relative to some address. Used, e.g. by shmem. + */ + unsigned long offset; + /* private data for every page-xfer engine */ union { struct /* local */ { @@ -35,8 +41,7 @@ struct page_xfer { extern int open_page_xfer(struct page_xfer *xfer, int fd_type, long id); struct page_pipe; -extern int page_xfer_dump_pages(struct page_xfer *, struct page_pipe *, - unsigned long off, bool dump_lazy); +extern int page_xfer_dump_pages(struct page_xfer *, struct page_pipe *, bool dump_lazy); extern int connect_to_page_server_to_send(void); extern int connect_to_page_server_to_recv(int epfd); extern int disconnect_from_page_server(void); diff --git a/criu/mem.c b/criu/mem.c index dbeffe12b..599c3036e 100644 --- a/criu/mem.c +++ b/criu/mem.c @@ -284,7 +284,7 @@ static int xfer_pages(struct page_pipe *pp, struct page_xfer *xfer, bool lazy) * pre-dump action (see pre_dump_one_task) */ timing_start(TIME_MEMWRITE); - ret = page_xfer_dump_pages(xfer, pp, 0, !lazy); + ret = page_xfer_dump_pages(xfer, pp, !lazy); timing_stop(TIME_MEMWRITE); return ret; diff --git a/criu/page-xfer.c b/criu/page-xfer.c index 5d4bf1128..737e05fa3 100644 --- a/criu/page-xfer.c +++ b/criu/page-xfer.c @@ -378,6 +378,8 @@ out: int open_page_xfer(struct page_xfer *xfer, int fd_type, long id) { + xfer->offset = 0; + if (opts.use_page_server) return open_page_server_xfer(xfer, fd_type, id); else @@ -385,10 +387,10 @@ int open_page_xfer(struct page_xfer *xfer, int fd_type, long id) } static int page_xfer_dump_hole(struct page_xfer *xfer, - struct iovec *hole, unsigned long off, u32 flags) + struct iovec *hole, u32 flags) { - BUG_ON(hole->iov_base < (void *)off); - hole->iov_base -= off; + BUG_ON(hole->iov_base < (void *)xfer->offset); + hole->iov_base -= xfer->offset; pr_debug("\th %p [%u]\n", hole->iov_base, (unsigned int)(hole->iov_len / PAGE_SIZE)); @@ -411,7 +413,7 @@ static int get_hole_flags(struct page_pipe *pp, int n) } static int dump_holes(struct page_xfer *xfer, struct page_pipe *pp, - unsigned int *cur_hole, void *limit, unsigned long off) + unsigned int *cur_hole, void *limit) { int ret; @@ -423,7 +425,7 @@ static int dump_holes(struct page_xfer *xfer, struct page_pipe *pp, break; hole_flags = get_hole_flags(pp, *cur_hole); - ret = page_xfer_dump_hole(xfer, &hole, off, hole_flags); + ret = page_xfer_dump_hole(xfer, &hole, hole_flags); if (ret) return ret; } @@ -432,7 +434,7 @@ static int dump_holes(struct page_xfer *xfer, struct page_pipe *pp, } int page_xfer_dump_pages(struct page_xfer *xfer, struct page_pipe *pp, - unsigned long off, bool dump_lazy) + bool dump_lazy) { struct page_pipe_buf *ppb; unsigned int cur_hole = 0; @@ -449,12 +451,12 @@ int page_xfer_dump_pages(struct page_xfer *xfer, struct page_pipe *pp, struct iovec iov = ppb->iov[i]; u32 flags = PE_PRESENT; - ret = dump_holes(xfer, pp, &cur_hole, iov.iov_base, off); + ret = dump_holes(xfer, pp, &cur_hole, iov.iov_base); if (ret) return ret; - BUG_ON(iov.iov_base < (void *)off); - iov.iov_base -= off; + BUG_ON(iov.iov_base < (void *)xfer->offset); + iov.iov_base -= xfer->offset; pr_debug("\tp %p [%u]\n", iov.iov_base, (unsigned int)(iov.iov_len / PAGE_SIZE)); @@ -475,7 +477,7 @@ int page_xfer_dump_pages(struct page_xfer *xfer, struct page_pipe *pp, } } - return dump_holes(xfer, pp, &cur_hole, NULL, off); + return dump_holes(xfer, pp, &cur_hole, NULL); } /* diff --git a/criu/shmem.c b/criu/shmem.c index cc5157d6b..7ab396359 100644 --- a/criu/shmem.c +++ b/criu/shmem.c @@ -628,7 +628,7 @@ int add_shmem_area(pid_t pid, VmaEntry *vma, u64 *map) return 0; } -static int dump_pages(struct page_pipe *pp, struct page_xfer *xfer, void *addr) +static int dump_pages(struct page_pipe *pp, struct page_xfer *xfer) { struct page_pipe_buf *ppb; @@ -640,7 +640,7 @@ static int dump_pages(struct page_pipe *pp, struct page_xfer *xfer, void *addr) return -1; } - return page_xfer_dump_pages(xfer, pp, (unsigned long)addr, true); + return page_xfer_dump_pages(xfer, pp, true); } static int next_data_segment(int fd, unsigned long pfn, @@ -687,6 +687,8 @@ static int do_dump_one_shmem(int fd, void *addr, struct shmem_info *si) if (err) goto err_pp; + xfer.offset = (unsigned long)addr; + for (pfn = 0; pfn < nrpages; pfn++) { unsigned int pgstate = PST_DIRTY; bool use_mc = true; @@ -718,7 +720,7 @@ again: ret = page_pipe_add_page(pp, pgaddr, 0); if (ret == -EAGAIN) { - ret = dump_pages(pp, &xfer, addr); + ret = dump_pages(pp, &xfer); if (ret) goto err_xfer; page_pipe_reinit(pp); @@ -727,7 +729,7 @@ again: goto err_xfer; } - ret = dump_pages(pp, &xfer, addr); + ret = dump_pages(pp, &xfer); err_xfer: xfer.close(&xfer);