Commit 11675c71 authored by Mike Rapoport's avatar Mike Rapoport Committed by Pavel Emelyanov

criu: pagemap: don't traverse the entire pagemap while seeking a page

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: 's avatarAndrey Vagin <avagin@openvz.org>
Signed-off-by: 's avatarMike Rapoport <rppt@linux.vnet.ibm.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent 70b072d4
......@@ -176,13 +176,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)
{
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;
......@@ -190,7 +194,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));
return 0;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment