[CRIU] [PATCH 2/3] shmem: Turn shmem-info into shared objects from shremap ones

Pavel Emelyanov xemul at parallels.com
Tue Dec 30 07:42:03 PST 2014


We have a nasty issue with it. Current code allocates these
entries in shremap area one by one. We do NOT allocate any
OTHER entries in this region, but if we will this array will
be spoiled.

Fortunately we no longer need shmem-infos as plain array,
neither we need one in restorer. So just turn this into plain
shared objects and collect them in a list.

Signed-off-by: Pavel Emelyanov <xemul at parallels.com>
---
 cr-restore.c       |  6 ------
 include/restorer.h |  2 --
 include/shmem.h    |  4 ----
 shmem.c            | 40 +++++++++++++---------------------------
 4 files changed, 13 insertions(+), 39 deletions(-)

diff --git a/cr-restore.c b/cr-restore.c
index dc855f7..2984dfe 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -168,9 +168,6 @@ static int root_prepare_shared(void)
 	if (prepare_shared_reg_files())
 		return -1;
 
-	if (prepare_shmem_restore())
-		return -1;
-
 	for (i = 0; i < ARRAY_SIZE(cinfos); i++) {
 		ret = collect_image(cinfos[i]);
 		if (ret)
@@ -2788,9 +2785,6 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
 	task_args->premmapped_addr = (unsigned long)rsti(current)->premmapped_addr;
 	task_args->premmapped_len = rsti(current)->premmapped_len;
 
-	task_args->shmems = rst_mem_remap_ptr(rst_shmems, RM_SHREMAP);
-	task_args->nr_shmems = nr_shmems;
-
 	task_args->nr_vmas = vmas->nr;
 	task_args->tgt_vmas = rst_mem_remap_ptr(tgt_vmas, RM_PRIVATE);
 
diff --git a/include/restorer.h b/include/restorer.h
index 8eefddc..7468105 100644
--- a/include/restorer.h
+++ b/include/restorer.h
@@ -106,8 +106,6 @@ struct task_restore_args {
 	int				nr_zombies;
 	thread_restore_fcall_t		clone_restore_fn;	/* helper address for clone() call */
 	struct thread_restore_args	*thread_args;		/* array of thread arguments */
-	struct shmem_info		*shmems;
-	unsigned int			nr_shmems;
 	struct task_entries		*task_entries;
 	void				*rst_mem;
 	unsigned long			rst_mem_size;
diff --git a/include/shmem.h b/include/shmem.h
index 1cef7da..47dd0fd 100644
--- a/include/shmem.h
+++ b/include/shmem.h
@@ -6,13 +6,9 @@
 
 struct _VmaEntry;
 extern int collect_shmem(int pid, struct _VmaEntry *vi);
-extern int prepare_shmem_restore(void);
 extern void show_saved_shmems(void);
 extern int get_shmem_fd(int pid, VmaEntry *vi);
 
-extern unsigned long nr_shmems;
-extern unsigned long rst_shmems;
-
 extern int cr_dump_shmem(void);
 extern int add_shmem_area(pid_t pid, VmaEntry *vma);
 
diff --git a/shmem.c b/shmem.c
index bd1a2e5..b153f19 100644
--- a/shmem.c
+++ b/shmem.c
@@ -46,51 +46,38 @@ struct shmem_info {
 	 */
 	int		count;		/* the number of regions */
 	int		self_count;	/* the number of regions, which belongs to "pid" */
-};
 
-unsigned long nr_shmems;
-unsigned long rst_shmems;
+	struct list_head l;
+};
 
-int prepare_shmem_restore(void)
-{
-	rst_shmems = rst_mem_cpos(RM_SHREMAP);
-	return 0;
-}
+/*
+ * This list is filled with shared objects before we fork
+ * any tasks. Thus the head is private (COW-ed) and the
+ * entries are all in shmem.
+ */
+static LIST_HEAD(shmems); /* XXX hash? tree? */
 
 void show_saved_shmems(void)
 {
-	int i;
 	struct shmem_info *si;
 
 	pr_info("\tSaved shmems:\n");
-	si = rst_mem_remap_ptr(rst_shmems, RM_SHREMAP);
-	for (i = 0; i < nr_shmems; i++, si++)
+	list_for_each_entry(si, &shmems, l)
 		pr_info("\t\tstart: 0x%016lx shmid: 0x%lx pid: %d\n",
 				si->start, si->shmid, si->pid);
 }
 
-static struct shmem_info *find_shmem(struct shmem_info *shmems,
-		int nr, unsigned long shmid)
+static struct shmem_info *find_shmem_by_id(unsigned long shmid)
 {
 	struct shmem_info *si;
-	int i;
 
-	for (i = 0, si = shmems; i < nr; i++, si++)
+	list_for_each_entry(si, &shmems, l)
 		if (si->shmid == shmid)
 			return si;
 
 	return NULL;
 }
 
-
-static struct shmem_info *find_shmem_by_id(unsigned long id)
-{
-	struct shmem_info *si;
-
-	si = rst_mem_remap_ptr(rst_shmems, RM_SHREMAP);
-	return find_shmem(si, nr_shmems, id);
-}
-
 int collect_shmem(int pid, VmaEntry *vi)
 {
 	unsigned long size = vi->pgoff + vi->end - vi->start;
@@ -124,7 +111,7 @@ int collect_shmem(int pid, VmaEntry *vi)
 		return 0;
 	}
 
-	si = rst_mem_alloc(sizeof(struct shmem_info), RM_SHREMAP);
+	si = shmalloc(sizeof(struct shmem_info));
 	if (!si)
 		return -1;
 
@@ -139,9 +126,8 @@ int collect_shmem(int pid, VmaEntry *vi)
 	si->fd    = -1;
 	si->count = 1;
 	si->self_count = 1;
-
-	nr_shmems++;
 	futex_init(&si->lock);
+	list_add_tail(&si->l, &shmems);
 
 	return 0;
 }
-- 
1.8.4.2




More information about the CRIU mailing list