[04/15] restore: Prepare on-restorer vmas earlier

Submitted by Pavel Emelianov on May 24, 2016, 11:34 a.m.

Details

Message ID 57443C4B.401@virtuozzo.com
State Superseded
Commit f1c22c422eb3e7c76ca41bc0cdf67b0b581507ba
Headers show

Commit Message

Pavel Emelianov May 24, 2016, 11:34 a.m.
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
---
 criu/cr-restore.c  | 27 +++------------------------
 criu/include/mem.h |  3 ++-
 criu/mem.c         | 42 ++++++++++++++++++++++++++++++------------
 criu/shmem.c       |  2 +-
 4 files changed, 36 insertions(+), 38 deletions(-)

Patch hide | download patch | download mbox

diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index d6b23d7..adc3035 100644
--- a/criu/cr-restore.c
+++ b/criu/cr-restore.c
@@ -505,7 +505,7 @@  static int restore_one_alive_task(int pid, CoreEntry *core)
 	if (prepare_file_locks(pid))
 		return -1;
 
-	if (open_vmas(current))
+	if (prepare_vmas(current, ta))
 		return -1;
 
 	if (fixup_sysv_shmems())
@@ -2701,9 +2701,6 @@  static int sigreturn_restore(pid_t pid, unsigned long ta_cp, CoreEntry *core)
 	struct thread_restore_args *thread_args;
 	struct restore_mem_zone *mz;
 
-	struct vma_area *vma;
-	unsigned long tgt_vmas;
-
 #ifdef CONFIG_VDSO
 	unsigned long vdso_rt_size = 0;
 #endif
@@ -2729,25 +2726,6 @@  static int sigreturn_restore(pid_t pid, unsigned long ta_cp, CoreEntry *core)
 	BUILD_BUG_ON(sizeof(struct thread_restore_args) & 1);
 
 	/*
-	 * Copy VMAs to private rst memory so that it's able to
-	 * walk them and m(un|re)map.
-	 */
-
-	tgt_vmas = rst_mem_align_cpos(RM_PRIVATE);
-	list_for_each_entry(vma, &vmas->h, list) {
-		VmaEntry *vme;
-
-		vme = rst_mem_alloc(sizeof(*vme), RM_PRIVATE);
-		if (!vme)
-			goto err_nv;
-
-		*vme = *vma->e;
-
-		if (vma_area_is_private(vma, kdat.task_size))
-			vma_premmaped_start(vme) = vma->premmaped_addr;
-	}
-
-	/*
 	 * Put info about AIO rings, they will get remapped
 	 */
 
@@ -2904,12 +2882,13 @@  static int sigreturn_restore(pid_t pid, unsigned long ta_cp, CoreEntry *core)
 
 	task_args->task_size = kdat.task_size;
 
+	task_args->vmas = rst_mem_remap_ptr((unsigned long)task_args->vmas, RM_PRIVATE);
+
 #define remap_array(name, nr, cpos)	do {				\
 		task_args->name##_n = nr;				\
 		task_args->name = rst_mem_remap_ptr(cpos, RM_PRIVATE);	\
 	} while (0)
 
-	remap_array(vmas,	  vmas->nr, tgt_vmas);
 	remap_array(posix_timers, posix_timers_nr, posix_timers_cpos);
 	remap_array(timerfd,	  rst_timerfd_nr, rst_timerfd_cpos);
 	remap_array(siginfo,	  siginfo_nr, siginfo_cpos);
diff --git a/criu/include/mem.h b/criu/include/mem.h
index 1bf3195..2e0ab95 100644
--- a/criu/include/mem.h
+++ b/criu/include/mem.h
@@ -24,7 +24,8 @@  extern int parasite_dump_pages_seized(struct parasite_ctl *ctl,
 #define PME_PFRAME_MASK		((1ULL << PME_PSHIFT_OFFSET) - 1)
 #define PME_PFRAME(x)		((x) & PME_PFRAME_MASK)
 
-int open_vmas(struct pstree_item *t);
+struct task_restore_args;
+int prepare_vmas(struct pstree_item *t, struct task_restore_args *ta);
 int unmap_guard_pages(struct pstree_item *t);
 int prepare_mappings(struct pstree_item *t);
 #endif /* __CR_MEM_H__ */
diff --git a/criu/mem.c b/criu/mem.c
index 6ca5da1..cf14242 100644
--- a/criu/mem.c
+++ b/criu/mem.c
@@ -18,6 +18,7 @@ 
 #include "shmem.h"
 #include "pstree.h"
 #include "restorer.h"
+#include "rst-malloc.h"
 #include "bitmap.h"
 #include "sk-packet.h"
 #include "files-reg.h"
@@ -501,7 +502,7 @@  static int map_private_vma(struct pstree_item *t,
 			return -1;
 		}
 
-		vma->vm_open = NULL; /* prevent from 2nd open in open_vmas */
+		vma->vm_open = NULL; /* prevent from 2nd open in prepare_vmas */
 	}
 
 	nr_pages = vma_entry_len(vma->e) / PAGE_SIZE;
@@ -889,24 +890,41 @@  int unmap_guard_pages(struct pstree_item *t)
 	return 0;
 }
 
-int open_vmas(struct pstree_item *t)
+int prepare_vmas(struct pstree_item *t, struct task_restore_args *ta)
 {
 	int pid = t->pid.virt;
 	struct vma_area *vma;
-	struct list_head *vmas = &rsti(t)->vmas.h;
+	struct vm_area_list *vmas = &rsti(t)->vmas;
 
-	list_for_each_entry(vma, vmas, list) {
-		if (!(vma_area_is(vma, VMA_AREA_REGULAR)))
-			continue;
+	ta->vmas = (VmaEntry *)rst_mem_align_cpos(RM_PRIVATE);
+	ta->vmas_n = vmas->nr;
 
-		pr_info("Opening 0x%016"PRIx64"-0x%016"PRIx64" 0x%016"PRIx64" (%x) vma\n",
-				vma->e->start, vma->e->end,
-				vma->e->pgoff, vma->e->status);
+	list_for_each_entry(vma, &vmas->h, list) {
+		VmaEntry *vme;
 
-		if (vma->vm_open && vma->vm_open(pid, vma)) {
-			pr_err("`- Can't open vma\n");
-			return -1;
+		if (vma_area_is(vma, VMA_AREA_REGULAR)) {
+			pr_info("Opening 0x%016"PRIx64"-0x%016"PRIx64" 0x%016"PRIx64" (%x) vma\n",
+					vma->e->start, vma->e->end,
+					vma->e->pgoff, vma->e->status);
+
+			if (vma->vm_open && vma->vm_open(pid, vma)) {
+				pr_err("`- Can't open vma\n");
+				return -1;
+			}
 		}
+
+		vme = rst_mem_alloc(sizeof(*vme), RM_PRIVATE);
+		if (!vme)
+			return -1;
+
+		/*
+		 * Copy VMAs to private rst memory so that it's able to
+		 * walk them and m(un|re)map.
+		 */
+		*vme = *vma->e;
+
+		if (vma_area_is_private(vma, kdat.task_size))
+			vma_premmaped_start(vme) = vma->premmaped_addr;
 	}
 
 	return 0;
diff --git a/criu/shmem.c b/criu/shmem.c
index 9941dc2..0d54452 100644
--- a/criu/shmem.c
+++ b/criu/shmem.c
@@ -247,7 +247,7 @@  static int open_shmem_sysv(int pid, struct vma_area *vma)
 		/*
 		 * Value that doesn't (shouldn't) match with any real
 		 * sysv shmem ID (thus it cannot be 0, as shmem id can)
-		 * and still is not negative to prevent open_vmas() from
+		 * and still is not negative to prevent prepare_vmas() from
 		 * treating it as error.
 		 */
 		ret_fd = SYSV_SHMEM_SKIP_FD;