[CRIU] [PATCH 02/15] restore: Move memzones from thread_args

Pavel Emelyanov xemul at virtuozzo.com
Tue May 24 04:33:57 PDT 2016


Right now memzone (stack and sigframe) sit on thread args, which
are allocated independently from rst-mem.

In the next patches task and thread args will be moved on rst-mem 
and will get unmapped by restorer at the end. Since both stack and
sigframe are required even after rst-mem unmap, memzon should live
independelntly.

The new restorer blob layout will be described in the next patch.

Signed-off-by: Pavel Emelyanov <xemul at virtuozzo.com>
---
 criu/cr-restore.c       | 43 ++++++++++++++++++-------------------------
 criu/include/restorer.h |  6 +++---
 criu/pie/restorer.c     |  6 +++---
 3 files changed, 24 insertions(+), 31 deletions(-)

diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index 6bc339b..54686c0 100644
--- a/criu/cr-restore.c
+++ b/criu/cr-restore.c
@@ -2683,9 +2683,11 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
 
 	long restore_bootstrap_len;
 	long rst_mem_size;
+	long memzone_size;
 
 	struct task_restore_args *task_args;
 	struct thread_restore_args *thread_args;
+	struct restore_mem_zone *mz;
 	long args_len;
 
 	struct vma_area *vma;
@@ -2790,7 +2792,8 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
 		goto err;
 
 	rst_mem_size = rst_mem_lock();
-	restore_bootstrap_len = restorer_len + args_len + rst_mem_size;
+	memzone_size = round_up(sizeof(struct restore_mem_zone) * current->nr_threads, page_size());
+	restore_bootstrap_len = restorer_len + memzone_size + args_len + rst_mem_size;
 	BUG_ON(restore_bootstrap_len & (PAGE_SIZE - 1));
 
 #ifdef CONFIG_VDSO
@@ -2840,7 +2843,7 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
 	exec_mem_hint += restorer_len;
 
 	/* VMA we need to run task_restore code */
-	mem = mmap((void *)exec_mem_hint, args_len,
+	mem = mmap((void *)exec_mem_hint, memzone_size + args_len,
 			PROT_READ | PROT_WRITE,
 			MAP_PRIVATE | MAP_ANON | MAP_FIXED, 0, 0);
 	if (mem != (void *)exec_mem_hint) {
@@ -2850,9 +2853,14 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
 
 	exec_mem_hint -= restorer_len;
 
-	memzero(mem, args_len);
-	task_args	= mem;
+	memzero(mem, memzone_size + args_len);
+	mz		= mem;
+	task_args	= mem + memzone_size;
 	thread_args	= (struct thread_restore_args *)(task_args + 1);
+	mem		+= memzone_size + args_len;
+
+	if (rst_mem_remap(mem))
+		goto err;
 
 	task_args->proc_fd = dup(get_service_fd(PROC_FD_OFF));
 	if (task_args->proc_fd < 0) {
@@ -2860,26 +2868,11 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
 		goto err;
 	}
 
-	/*
-	 * Get a reference to shared memory area which is
-	 * used to signal if shmem restoration complete
-	 * from low-level restore code.
-	 *
-	 * This shmem area is mapped right after the whole area of
-	 * sigreturn rt code. Note we didn't allocated it before
-	 * but this area is taken into account for 'hint' memory
-	 * address.
-	 */
-
-	mem += args_len;
-	if (rst_mem_remap(mem))
-		goto err;
-
 	task_args->breakpoint = &rsti(current)->breakpoint;
 	task_args->task_entries = rst_mem_remap_ptr(task_entries_pos, RM_SHREMAP);
 
-	task_args->rst_mem = mem;
-	task_args->rst_mem_size = rst_mem_size;
+	task_args->rst_mem = mem - args_len;
+	task_args->rst_mem_size = rst_mem_size + args_len;
 
 	task_args->bootstrap_start = (void *)exec_mem_hint;
 	task_args->bootstrap_len = restore_bootstrap_len;
@@ -2983,7 +2976,8 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
 				goto err;
 		}
 
-		sigframe = (struct rt_sigframe *)thread_args[i].mem_zone.rt_sigframe;
+		thread_args[i].mz = mz + i;
+		sigframe = (struct rt_sigframe *)&mz[i].rt_sigframe;
 
 		if (construct_sigframe(sigframe, sigframe, tcore))
 			goto err;
@@ -2992,8 +2986,7 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
 			core_entry__free_unpacked(tcore, NULL);
 
 		pr_info("Thread %4d stack %8p rt_sigframe %8p\n",
-				i, thread_args[i].mem_zone.stack,
-				thread_args[i].mem_zone.rt_sigframe);
+				i, mz[i].stack, mz[i].rt_sigframe);
 
 	}
 
@@ -3010,7 +3003,7 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
 	task_args->vdso_rt_size = vdso_rt_size;
 #endif
 
-	new_sp = restorer_stack(task_args->t);
+	new_sp = restorer_stack(task_args->t->mz);
 
 	ret = prepare_itimers(pid, core, task_args);
 	if (ret < 0)
diff --git a/criu/include/restorer.h b/criu/include/restorer.h
index 2600678..fad9e09 100644
--- a/criu/include/restorer.h
+++ b/criu/include/restorer.h
@@ -75,7 +75,7 @@ struct thread_creds_args {
 };
 
 struct thread_restore_args {
-	struct restore_mem_zone		mem_zone;
+	struct restore_mem_zone		*mz;
 
 	int				pid;
 	UserRegsEntry			gpregs;
@@ -190,9 +190,9 @@ struct task_restore_args {
 #define RESTORE_ALIGN_STACK(start, size)	\
 	(ALIGN((start) + (size) - 16, 16))
 
-static inline unsigned long restorer_stack(struct thread_restore_args *a)
+static inline unsigned long restorer_stack(struct restore_mem_zone *mz)
 {
-	return RESTORE_ALIGN_STACK((long)a->mem_zone.stack, RESTORE_STACK_SIZE);
+	return RESTORE_ALIGN_STACK((long)&mz->stack, RESTORE_STACK_SIZE);
 }
 
 enum {
diff --git a/criu/pie/restorer.c b/criu/pie/restorer.c
index aa36fa9..7d63ba2 100644
--- a/criu/pie/restorer.c
+++ b/criu/pie/restorer.c
@@ -459,7 +459,7 @@ long __export_restore_thread(struct thread_restore_args *args)
 		goto core_restore_end;
 	}
 
-	rt_sigframe = (void *)args->mem_zone.rt_sigframe;
+	rt_sigframe = (void *)&args->mz->rt_sigframe;
 
 	if (restore_thread_common(args))
 		goto core_restore_end;
@@ -1313,7 +1313,7 @@ long __export_restore_task(struct task_restore_args *args)
 	 * registers from the frame, set them up and
 	 * finally pass execution to the new IP.
 	 */
-	rt_sigframe = (void *)args->t->mem_zone.rt_sigframe;
+	rt_sigframe = (void *)&args->t->mz->rt_sigframe;
 
 	if (restore_thread_common(args->t))
 		goto core_restore_end;
@@ -1364,7 +1364,7 @@ long __export_restore_task(struct task_restore_args *args)
 			if (thread_args[i].pid == args->t->pid)
 				continue;
 
-			new_sp = restorer_stack(thread_args + i);
+			new_sp = restorer_stack(thread_args[i].mz);
 			last_pid_len = vprint_num(last_pid_buf, sizeof(last_pid_buf), thread_args[i].pid - 1, &s);
 			sys_lseek(fd, 0, SEEK_SET);
 			ret = sys_write(fd, s, last_pid_len);
-- 
2.5.0



More information about the CRIU mailing list