[CRIU] [PATCH v2] criu: pagemap: don't traverse the entire pagemap while seeking a page
Mike Rapoport
rppt at linux.vnet.ibm.com
Sat Sep 17 23:28:19 PDT 2016
Since commit 95009c4c6d5 (criu: pagemap: introduce advance() helper for
pagemap iteration) seek_pagemap_page traverses the entire pagemap, rather
than starts each time from the last pagemap that was used.
With large pagemaps (like, e.g. in maps05 case) the new behavior causes
exponential increase in amount of calls to skip_pagemap_page for every new
snapshot.
Let's restore the original behavior.
Fixes: #217
Reported-by: Andrey Vagin <avagin at openvz.org>
Signed-off-by: Mike Rapoport <rppt at linux.vnet.ibm.com>
---
Please discard v1, because it misses additional condition to stop pagemap
iteration...
criu/pagemap.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/criu/pagemap.c b/criu/pagemap.c
index 71ae11e..49362e3 100644
--- a/criu/pagemap.c
+++ b/criu/pagemap.c
@@ -166,13 +166,17 @@ static void skip_pagemap_pages(struct page_read *pr, unsigned long len)
static int seek_pagemap_page(struct page_read *pr, unsigned long vaddr,
bool warn)
{
- pr->reset(pr);
+ if (!pr->pe)
+ advance(pr);
- while (advance(pr)) {
+ do {
unsigned long start = pr->pe->vaddr;
unsigned long len = pr->pe->nr_pages * PAGE_SIZE;
unsigned long end = start + len;
+ if (vaddr < pr->cvaddr)
+ break;
+
if (vaddr >= start && vaddr < end) {
skip_pagemap_pages(pr, vaddr - pr->cvaddr);
return 1;
@@ -180,7 +184,7 @@ static int seek_pagemap_page(struct page_read *pr, unsigned long vaddr,
if (end <= vaddr)
skip_pagemap_pages(pr, end - pr->cvaddr);
- }
+ } while (advance(pr));
if (warn)
pr_err("Missing %lx in parent pagemap\n", vaddr);
--
1.9.1
More information about the CRIU
mailing list