[CRIU] [PATCH 04/10] uffd: Scan VMAs linearly when collecting pagemaps

Pavel Emelyanov xemul at virtuozzo.com
Fri Nov 11 21:24:24 PST 2016


Right now each pagemap results in scanning vmas list
from the beginning. But since pagemaps go incrementally
(do they? I believe they do), we may continue scanning
list of vmas from the last stop.

Signed-off-by: Pavel Emelyanov <xemul at virtuozzo.com>
---
 criu/uffd.c | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/criu/uffd.c b/criu/uffd.c
index 5c34007..950a5ea 100644
--- a/criu/uffd.c
+++ b/criu/uffd.c
@@ -499,6 +499,7 @@ static int collect_uffd_pages(struct page_read *pr, struct lazy_pages_info *lpi)
 
 	ps = page_size();
 	vmas = &rsti(item)->vmas;
+	vma = list_first_entry(&vmas->h, struct vma_area, list);
 
 	while (1) {
 		rc = pr->get_pagemap(pr, &iov);
@@ -517,18 +518,20 @@ static int collect_uffd_pages(struct page_read *pr, struct lazy_pages_info *lpi)
 			 * are relevant for userfaultfd handling.
 			 * Loop over all VMAs to see if the flags matching.
 			 */
-			list_for_each_entry(vma, &vmas->h, list) {
+			list_for_each_entry_from(vma, &vmas->h, list) {
 				/*
 				 * This loop assumes that base can actually be found
 				 * in the VMA list.
 				 */
-				if (base >= vma->e->start && base < vma->e->end) {
-					if (vma_entry_can_be_lazy(vma->e)) {
-						if(!pagemap_in_parent(pr->pe))
-							uffd_page = true;
-						break;
-					}
-				}
+
+				if (base >= vma->e->end)
+					continue;
+
+				if (vma->e->start <= base && vma_entry_can_be_lazy(vma->e) &&
+						!pagemap_in_parent(pr->pe))
+					uffd_page = true;
+
+				break;
 			}
 
 			/* This is not a page we are looking for. Move along */
-- 
2.5.0



More information about the CRIU mailing list