[CRIU] [PATCH 1/3] page-read: Add skip_zero argument to ->advance method
Pavel Emelyanov
xemul at virtuozzo.com
Wed Nov 30 02:47:38 PST 2016
And optimize the get_pagemap() caller to reuse this.
Signed-off-by: Pavel Emelyanov <xemul at virtuozzo.com>
---
criu/include/pagemap.h | 4 ++--
criu/page-xfer.c | 4 ++--
criu/pagemap.c | 29 ++++++++++++-----------------
criu/uffd.c | 2 +-
4 files changed, 17 insertions(+), 22 deletions(-)
diff --git a/criu/include/pagemap.h b/criu/include/pagemap.h
index ea106ec..6f41ebc 100644
--- a/criu/include/pagemap.h
+++ b/criu/include/pagemap.h
@@ -50,8 +50,8 @@ struct page_read {
/* reads page from current pagemap */
int (*read_pages)(struct page_read *, unsigned long vaddr, int nr,
void *, unsigned flags);
- /* Advance page_read to the next entry (including zero pagemaps) */
- int (*advance)(struct page_read *pr);
+ /* Advance page_read to the next entry */
+ int (*advance)(struct page_read *pr, bool skip_zero);
void (*close)(struct page_read *);
void (*skip_pages)(struct page_read *, unsigned long len);
int (*seek_pagemap)(struct page_read *pr, unsigned long vaddr,
diff --git a/criu/page-xfer.c b/criu/page-xfer.c
index 315d152..b60863a 100644
--- a/criu/page-xfer.c
+++ b/criu/page-xfer.c
@@ -823,7 +823,7 @@ static int fill_page_pipe(struct page_read *pr, struct page_pipe *pp)
pr->reset(pr);
- while (pr->advance(pr)) {
+ while (pr->advance(pr, false)) {
unsigned long vaddr = pr->pe->vaddr;
for (i = 0; i < pr->pe->nr_pages; i++, vaddr += PAGE_SIZE) {
@@ -867,7 +867,7 @@ static int page_pipe_from_pagemap(struct page_pipe **pp, int pid)
return -1;
}
- while (pr.advance(&pr))
+ while (pr.advance(&pr, false))
if (pagemap_present(pr.pe))
nr_pages += pr.pe->nr_pages;
diff --git a/criu/pagemap.c b/criu/pagemap.c
index a165a43..5ba4c3f 100644
--- a/criu/pagemap.c
+++ b/criu/pagemap.c
@@ -138,26 +138,24 @@ int dedup_one_iovec(struct page_read *pr, struct iovec *iov)
return 0;
}
-static int advance(struct page_read *pr)
+static int advance(struct page_read *pr, bool skip_zero)
{
- pr->curr_pme++;
- if (pr->curr_pme >= pr->nr_pmes)
- return 0;
+ do {
+ pr->curr_pme++;
+ if (pr->curr_pme >= pr->nr_pmes)
+ return 0;
- pr->pe = pr->pmes[pr->curr_pme];
- pr->cvaddr = pr->pe->vaddr;
+ pr->pe = pr->pmes[pr->curr_pme];
+ pr->cvaddr = pr->pe->vaddr;
+ } while (skip_zero && pagemap_zero(pr->pe));
return 1;
}
static int get_pagemap(struct page_read *pr, struct iovec *iov)
{
- for (;;) {
- if (!advance(pr))
- return 0;
- if (!pagemap_zero(pr->pe))
- break;
- }
+ if (!advance(pr, true))
+ return 0;
if (pagemap_in_parent(pr->pe) && !pr->parent) {
pr_err("No parent for snapshot pagemap\n");
@@ -183,16 +181,13 @@ static int seek_pagemap(struct page_read *pr, unsigned long vaddr,
bool skip_zero)
{
if (!pr->pe)
- advance(pr);
+ advance(pr, skip_zero);
do {
unsigned long start = pr->pe->vaddr;
unsigned long len = pr->pe->nr_pages * PAGE_SIZE;
unsigned long end = start + len;
- if (skip_zero && pagemap_zero(pr->pe))
- continue;
-
if (vaddr < pr->cvaddr)
break;
@@ -203,7 +198,7 @@ static int seek_pagemap(struct page_read *pr, unsigned long vaddr,
if (end <= vaddr)
skip_pagemap_pages(pr, end - pr->cvaddr);
- } while (advance(pr));
+ } while (advance(pr, skip_zero));
return 0;
}
diff --git a/criu/uffd.c b/criu/uffd.c
index b7bffc1..8eaf886 100644
--- a/criu/uffd.c
+++ b/criu/uffd.c
@@ -397,7 +397,7 @@ static int collect_lazy_iovecs(struct lazy_pages_info *lpi)
if (!mm)
return -1;
- while (pr->advance(pr)) {
+ while (pr->advance(pr, false)) {
if (!pagemap_lazy(pr->pe))
continue;
--
2.5.0
More information about the CRIU
mailing list