[CRIU] [PATCH v2 02/11] criu: lazy-pages: move find_vmas and related code around
Mike Rapoport
rppt at linux.vnet.ibm.com
Sun Nov 13 01:52:35 PST 2016
Moving the find_vmas and collect_uffd_pages functions before they are
actually used. This allows to drop forward declaration of find_vmas and
will make subsequent refactoring cleaner.
Signed-off-by: Mike Rapoport <rppt at linux.vnet.ibm.com>
---
criu/uffd.c | 310 ++++++++++++++++++++++++++++++------------------------------
1 file changed, 154 insertions(+), 156 deletions(-)
diff --git a/criu/uffd.c b/criu/uffd.c
index 8d5e633..48c32a0 100644
--- a/criu/uffd.c
+++ b/criu/uffd.c
@@ -320,7 +320,160 @@ out:
return -1;
}
-static int find_vmas(struct lazy_pages_info *lpi);
+#define UFFD_FLAG_SENT 0x1
+
+struct uffd_pages_struct {
+ struct list_head list;
+ unsigned long addr;
+ int flags;
+};
+
+static int collect_uffd_pages(struct page_read *pr, struct lazy_pages_info *lpi)
+{
+ unsigned long base;
+ int i;
+ struct iovec iov;
+ unsigned long nr_pages;
+ unsigned long ps;
+ int rc;
+ struct uffd_pages_struct *uffd_pages;
+ struct vma_area *vma;
+ struct vm_area_list *vmas;
+ struct pstree_item *item = pstree_item_by_virt(lpi->pid);
+
+ BUG_ON(!item);
+
+ vmas = &rsti(item)->vmas;
+
+ rc = pr->get_pagemap(pr, &iov);
+ if (rc <= 0)
+ return 0;
+
+ ps = page_size();
+ nr_pages = iov.iov_len / ps;
+ base = (unsigned long) iov.iov_base;
+ pr_debug("iov.iov_base 0x%lx (%ld pages)\n", base, nr_pages);
+
+ for (i = 0; i < nr_pages; i++) {
+ bool uffd_page = false;
+ base = (unsigned long) iov.iov_base + (i * ps);
+ /*
+ * Only pages which are MAP_ANONYMOUS and MAP_PRIVATE
+ * are relevant for userfaultfd handling.
+ * Loop over all VMAs to see if the flags matching.
+ */
+ list_for_each_entry(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;
+ }
+ }
+ }
+
+ /* This is not a page we are looking for. Move along */
+ if (!uffd_page)
+ continue;
+
+ pr_debug("Adding 0x%lx to our list\n", base);
+
+ uffd_pages = xzalloc(sizeof(struct uffd_pages_struct));
+ if (!uffd_pages)
+ return -1;
+ uffd_pages->addr = base;
+ list_add(&uffd_pages->list, &lpi->pages);
+ }
+
+ return 1;
+}
+
+/*
+ * Setting up criu infrastructure and scan for VMAs.
+ */
+static int find_vmas(struct lazy_pages_info *lpi)
+{
+ struct cr_img *img;
+ int ret;
+ struct vm_area_list vmas;
+ int vn = 0;
+ struct rst_info *ri;
+ struct uffd_pages_struct *uffd_pages;
+ struct pstree_item *item = pstree_item_by_virt(lpi->pid);
+
+ BUG_ON(!item);
+
+ vm_area_list_init(&vmas);
+
+ ri = rsti(item);
+ if (!ri)
+ return -1;
+
+ img = open_image(CR_FD_MM, O_RSTR, lpi->pid);
+ if (!img)
+ return -1;
+
+ ret = pb_read_one_eof(img, &ri->mm, PB_MM);
+ close_image(img);
+ if (ret == -1)
+ return -1;
+
+ pr_debug("Found %zd VMAs in image\n", ri->mm->n_vmas);
+
+ while (vn < ri->mm->n_vmas) {
+ struct vma_area *vma;
+
+ ret = -1;
+ vma = alloc_vma_area();
+ if (!vma)
+ goto out;
+
+ ret = 0;
+ ri->vmas.nr++;
+ vma->e = ri->mm->vmas[vn++];
+
+ list_add_tail(&vma->list, &ri->vmas.h);
+
+ if (vma_area_is_private(vma, kdat.task_size)) {
+ vmas.priv_size += vma_area_len(vma);
+ if (vma->e->flags & MAP_GROWSDOWN)
+ vmas.priv_size += PAGE_SIZE;
+ }
+
+ pr_info("vma 0x%"PRIx64" 0x%"PRIx64"\n", vma->e->start, vma->e->end);
+ }
+
+ ret = open_page_read(lpi->pid, &lpi->pr, PR_TASK);
+ if (ret <= 0) {
+ ret = -1;
+ goto out;
+ }
+ /*
+ * This puts all pages which should be handled by userfaultfd
+ * in the list uffd_list. This list is later used to detect if
+ * a page has already been transferred or if it needs to be
+ * pushed into the process using userfaultfd.
+ */
+ do {
+ ret = collect_uffd_pages(&lpi->pr, lpi);
+ if (ret == -1) {
+ goto out;
+ }
+ } while (ret);
+
+ /* Count detected pages */
+ list_for_each_entry(uffd_pages, &lpi->pages, list)
+ ret++;
+
+ pr_debug("Found %d pages to be handled by UFFD\n", ret);
+
+out:
+ return ret;
+}
static int ud_open(int client, struct lazy_pages_info **_lpi)
{
@@ -402,14 +555,6 @@ static int get_page(struct lazy_pages_info *lpi, unsigned long addr, void *dest)
return 1;
}
-#define UFFD_FLAG_SENT 0x1
-
-struct uffd_pages_struct {
- struct list_head list;
- unsigned long addr;
- int flags;
-};
-
static int uffd_copy_page(struct lazy_pages_info *lpi, __u64 address,
void *dest)
{
@@ -484,70 +629,6 @@ static int uffd_handle_page(struct lazy_pages_info *lpi, __u64 address,
return rc;
}
-static int collect_uffd_pages(struct page_read *pr, struct lazy_pages_info *lpi)
-{
- unsigned long base;
- int i;
- struct iovec iov;
- unsigned long nr_pages;
- unsigned long ps;
- int rc;
- struct uffd_pages_struct *uffd_pages;
- struct vma_area *vma;
- struct vm_area_list *vmas;
- struct pstree_item *item = pstree_item_by_virt(lpi->pid);
-
- BUG_ON(!item);
-
- vmas = &rsti(item)->vmas;
-
- rc = pr->get_pagemap(pr, &iov);
- if (rc <= 0)
- return 0;
-
- ps = page_size();
- nr_pages = iov.iov_len / ps;
- base = (unsigned long) iov.iov_base;
- pr_debug("iov.iov_base 0x%lx (%ld pages)\n", base, nr_pages);
-
- for (i = 0; i < nr_pages; i++) {
- bool uffd_page = false;
- base = (unsigned long) iov.iov_base + (i * ps);
- /*
- * Only pages which are MAP_ANONYMOUS and MAP_PRIVATE
- * are relevant for userfaultfd handling.
- * Loop over all VMAs to see if the flags matching.
- */
- list_for_each_entry(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;
- }
- }
- }
-
- /* This is not a page we are looking for. Move along */
- if (!uffd_page)
- continue;
-
- pr_debug("Adding 0x%lx to our list\n", base);
-
- uffd_pages = xzalloc(sizeof(struct uffd_pages_struct));
- if (!uffd_pages)
- return -1;
- uffd_pages->addr = base;
- list_add(&uffd_pages->list, &lpi->pages);
- }
-
- return 1;
-}
-
static int handle_remaining_pages(struct lazy_pages_info *lpi, void *dest)
{
struct uffd_pages_struct *uffd_pages;
@@ -596,89 +677,6 @@ static int handle_regular_pages(struct lazy_pages_info *lpi, void *dest,
return 0;
}
-/*
- * Setting up criu infrastructure and scan for VMAs.
- */
-static int find_vmas(struct lazy_pages_info *lpi)
-{
- struct cr_img *img;
- int ret;
- struct vm_area_list vmas;
- int vn = 0;
- struct rst_info *ri;
- struct uffd_pages_struct *uffd_pages;
- struct pstree_item *item = pstree_item_by_virt(lpi->pid);
-
- BUG_ON(!item);
-
- vm_area_list_init(&vmas);
-
- ri = rsti(item);
- if (!ri)
- return -1;
-
- img = open_image(CR_FD_MM, O_RSTR, lpi->pid);
- if (!img)
- return -1;
-
- ret = pb_read_one_eof(img, &ri->mm, PB_MM);
- close_image(img);
- if (ret == -1)
- return -1;
-
- pr_debug("Found %zd VMAs in image\n", ri->mm->n_vmas);
-
- while (vn < ri->mm->n_vmas) {
- struct vma_area *vma;
-
- ret = -1;
- vma = alloc_vma_area();
- if (!vma)
- goto out;
-
- ret = 0;
- ri->vmas.nr++;
- vma->e = ri->mm->vmas[vn++];
-
- list_add_tail(&vma->list, &ri->vmas.h);
-
- if (vma_area_is_private(vma, kdat.task_size)) {
- vmas.priv_size += vma_area_len(vma);
- if (vma->e->flags & MAP_GROWSDOWN)
- vmas.priv_size += PAGE_SIZE;
- }
-
- pr_info("vma 0x%"PRIx64" 0x%"PRIx64"\n", vma->e->start, vma->e->end);
- }
-
- ret = open_page_read(lpi->pid, &lpi->pr, PR_TASK);
- if (ret <= 0) {
- ret = -1;
- goto out;
- }
- /*
- * This puts all pages which should be handled by userfaultfd
- * in the list uffd_list. This list is later used to detect if
- * a page has already been transferred or if it needs to be
- * pushed into the process using userfaultfd.
- */
- do {
- ret = collect_uffd_pages(&lpi->pr, lpi);
- if (ret == -1) {
- goto out;
- }
- } while (ret);
-
- /* Count detected pages */
- list_for_each_entry(uffd_pages, &lpi->pages, list)
- ret++;
-
- pr_debug("Found %d pages to be handled by UFFD\n", ret);
-
-out:
- return ret;
-}
-
static int handle_user_fault(struct lazy_pages_info *lpi, void *dest)
{
struct uffd_msg msg;
--
1.9.1
More information about the CRIU
mailing list