[CRIU] [PATCH 2/9] page-pipe: Support holes in page-pipe iov map
Pavel Emelyanov
xemul at parallels.com
Thu Apr 11 09:49:56 EDT 2013
Holes are regions, that don't have pages in them (i.e. -- no
pages in pipes). These holes are in separate iovs array since
we should have straight arrays of iovs for non-holes, which is
in turd required to push it into vmsplice in _one_ chunk.
Signed-off-by: Pavel Emelyanov <xemul at parallels.com>
---
include/page-pipe.h | 5 +++++
page-pipe.c | 35 +++++++++++++++++++++++++++++++++++
2 files changed, 40 insertions(+)
diff --git a/include/page-pipe.h b/include/page-pipe.h
index cdf3aec..fbba122 100644
--- a/include/page-pipe.h
+++ b/include/page-pipe.h
@@ -18,9 +18,14 @@ struct page_pipe {
unsigned int nr_iovs;
unsigned int free_iov;
struct iovec *iovs;
+
+ unsigned int nr_holes;
+ unsigned int free_hole;
+ struct iovec *holes;
};
struct page_pipe *create_page_pipe(unsigned int nr, struct iovec *);
void destroy_page_pipe(struct page_pipe *p);
int page_pipe_add_page(struct page_pipe *p, unsigned long addr);
+int page_pipe_add_hole(struct page_pipe *p, unsigned long addr);
#endif
diff --git a/page-pipe.c b/page-pipe.c
index 5295839..ab2eae7 100644
--- a/page-pipe.c
+++ b/page-pipe.c
@@ -47,6 +47,10 @@ struct page_pipe *create_page_pipe(unsigned int nr_segs, struct iovec *iovs)
pp->iovs = iovs;
pp->free_iov = 0;
+ pp->nr_holes = 0;
+ pp->free_hole = 0;
+ pp->holes = NULL;
+
if (page_pipe_grow(pp))
return NULL;
}
@@ -137,3 +141,34 @@ int page_pipe_add_page(struct page_pipe *pp, unsigned long addr)
BUG_ON(ret > 0);
return ret;
}
+
+#define PP_HOLES_BATCH 32
+
+int page_pipe_add_hole(struct page_pipe *pp, unsigned long addr)
+{
+ struct iovec *iov;
+
+ if (pp->free_hole >= pp->nr_holes) {
+ pp->holes = xrealloc(pp->holes,
+ (pp->nr_holes + PP_HOLES_BATCH) * sizeof(struct iovec));
+ if (!pp->holes)
+ return -1;
+
+ pp->nr_holes += PP_HOLES_BATCH;
+ }
+
+ if (pp->free_hole) {
+ iov = &pp->holes[pp->free_hole - 1];
+ if ((unsigned long)iov->iov_base + iov->iov_len == addr) {
+ iov->iov_len += PAGE_SIZE;
+ goto out;
+ }
+ }
+
+ iov = &pp->holes[pp->free_hole];
+ iov->iov_base = (void *)addr;
+ iov->iov_len = PAGE_SIZE;
+ pp->free_hole++;
+out:
+ return 0;
+}
--
1.7.11.7
More information about the CRIU
mailing list