[CRIU] [PATCH v5 4/8] criu: page-{pipe, xfer}: add helper function for dumping holes
Mike Rapoport
rppt at linux.vnet.ibm.com
Tue Jun 28 22:55:09 PDT 2016
Signed-off-by: Mike Rapoport <rppt at linux.vnet.ibm.com>
---
criu/include/page-pipe.h | 1 +
criu/page-pipe.c | 2 ++
criu/page-xfer.c | 54 +++++++++++++++++++++++-------------------------
3 files changed, 29 insertions(+), 28 deletions(-)
diff --git a/criu/include/page-pipe.h b/criu/include/page-pipe.h
index a018af0..f11071c 100644
--- a/criu/include/page-pipe.h
+++ b/criu/include/page-pipe.h
@@ -83,6 +83,7 @@ struct page_pipe_buf {
struct page_pipe_iovs {
unsigned int nr_iovs; /* number of iovs */
unsigned int free_iov; /* number of iovs in use */
+ unsigned int busy_iov; /* first iov that not yet dumped */
struct iovec *iovs; /* iovs */
};
diff --git a/criu/page-pipe.c b/criu/page-pipe.c
index 9bc7eaf..d002c3a 100644
--- a/criu/page-pipe.c
+++ b/criu/page-pipe.c
@@ -149,10 +149,12 @@ struct page_pipe *create_page_pipe(unsigned int nr_segs,
pp->pages.nr_iovs = nr_segs;
pp->pages.iovs = iovs;
pp->pages.free_iov = 0;
+ pp->pages.busy_iov = 0;
pp->holes.nr_iovs = 0;
pp->holes.free_iov = 0;
pp->holes.iovs = NULL;
+ pp->holes.busy_iov = 0;
pp->chunk_mode = chunk_mode;
diff --git a/criu/page-xfer.c b/criu/page-xfer.c
index 4bb8ea0..32b50f7 100644
--- a/criu/page-xfer.c
+++ b/criu/page-xfer.c
@@ -320,17 +320,35 @@ int open_page_xfer(struct page_xfer *xfer, int fd_type, long id)
return open_page_local_xfer(xfer, fd_type, id);
}
+static int dump_hole(struct page_xfer *xfer, struct page_pipe_iovs *iov,
+ void *limit, unsigned long off)
+{
+ while (iov->busy_iov < iov->free_iov) {
+ struct iovec *hole = &iov->iovs[iov->busy_iov];
+
+ if (limit && hole->iov_base >= limit)
+ break;
+
+ BUG_ON(hole->iov_base < (void *)off);
+ hole->iov_base -= off;
+ pr_debug("\th %p [%u]\n", hole->iov_base,
+ (unsigned int)(hole->iov_len / PAGE_SIZE));
+ if (xfer->write_hole(xfer, hole))
+ return -1;
+
+ iov->busy_iov++;
+ }
+
+ return 0;
+}
+
int page_xfer_dump_pages(struct page_xfer *xfer, struct page_pipe *pp,
unsigned long off)
{
struct page_pipe_buf *ppb;
- struct iovec *hole = NULL;
pr_debug("Transfering pages:\n");
- if (pp->holes.free_iov)
- hole = &pp->holes.iovs[0];
-
list_for_each_entry(ppb, &pp->bufs, l) {
int i;
@@ -339,18 +357,8 @@ int page_xfer_dump_pages(struct page_xfer *xfer, struct page_pipe *pp,
for (i = 0; i < ppb->nr_segs; i++) {
struct iovec *iov = &ppb->iov[i];
- while (hole && (hole->iov_base < iov->iov_base)) {
- BUG_ON(hole->iov_base < (void *)off);
- hole->iov_base -= off;
- pr_debug("\th %p [%u]\n", hole->iov_base,
- (unsigned int)(hole->iov_len / PAGE_SIZE));
- if (xfer->write_hole(xfer, hole))
- return -1;
-
- hole++;
- if (hole >= &pp->holes.iovs[pp->holes.free_iov])
- hole = NULL;
- }
+ if (dump_hole(xfer, &pp->holes, iov->iov_base, off))
+ return -1;
BUG_ON(iov->iov_base < (void *)off);
iov->iov_base -= off;
@@ -364,18 +372,8 @@ int page_xfer_dump_pages(struct page_xfer *xfer, struct page_pipe *pp,
}
}
- while (hole) {
- BUG_ON(hole->iov_base < (void *)off);
- hole->iov_base -= off;
- pr_debug("\th* %p [%u]\n", hole->iov_base,
- (unsigned int)(hole->iov_len / PAGE_SIZE));
- if (xfer->write_hole(xfer, hole))
- return -1;
-
- hole++;
- if (hole >= &pp->holes.iovs[pp->holes.free_iov])
- hole = NULL;
- }
+ if (dump_hole(xfer, &pp->holes, NULL, off))
+ return -1;
return 0;
}
--
1.9.1
More information about the CRIU
mailing list