[CRIU] [PATCH 3/3] rst: Fix timerfd rst memory management

Pavel Emelyanov xemul at parallels.com
Thu Jun 25 05:36:57 PDT 2015


It's similar to previous patch with tcp mem -- no need to
realloc big arrays and then memcpy data between them. It's
enough just to walk timerfd objects at the very end.

Signed-off-by: Pavel Emelyanov <xemul at parallels.com>
---
 cr-restore.c      | 10 ++--------
 include/timerfd.h |  8 +++-----
 timerfd.c         | 55 +++++++++++++++++++++++++++++++++++++------------------
 3 files changed, 42 insertions(+), 31 deletions(-)

diff --git a/cr-restore.c b/cr-restore.c
index f1e96af..dd23488 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -2648,9 +2648,6 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
 	struct vma_area *vma;
 	unsigned long tgt_vmas;
 
-	void *timerfd_mem;
-	unsigned long timerfd_mem_cpos;
-
 #ifdef CONFIG_VDSO
 	unsigned long vdso_rt_size = 0;
 	unsigned long vdso_rt_delta = 0;
@@ -2725,11 +2722,8 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
 	 * Copy timerfd params for restorer args, we need to proceed
 	 * timer setting at the very late.
 	 */
-	timerfd_mem_cpos = rst_mem_cpos(RM_PRIVATE);
-	timerfd_mem = rst_mem_alloc(rst_timerfd_len(), RM_PRIVATE);
-	if (!timerfd_mem)
+	if (rst_timerfd_prep())
 		goto err_nv;
-	memcpy(timerfd_mem, rst_timerfd, rst_timerfd_len());
 
 	/*
 	 * We're about to search for free VM area and inject the restorer blob
@@ -2877,7 +2871,7 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
 
 	remap_array(vmas,	  vmas->nr, tgt_vmas);
 	remap_array(posix_timers, posix_timers_nr, posix_timers_cpos);
-	remap_array(timerfd,	  rst_timerfd_nr, timerfd_mem_cpos);
+	remap_array(timerfd,	  rst_timerfd_nr, rst_timerfd_cpos);
 	remap_array(siginfo,	  siginfo_nr, siginfo_cpos);
 	remap_array(tcp_socks,	  rst_tcp_socks_nr, rst_tcp_socks_cpos);
 	remap_array(rings,	  mm->n_aios, aio_rings);
diff --git a/include/timerfd.h b/include/timerfd.h
index 89525dc..67b9187 100644
--- a/include/timerfd.h
+++ b/include/timerfd.h
@@ -19,13 +19,11 @@ struct restore_timerfd {
 
 extern const struct fdtype_ops timerfd_dump_ops;
 extern struct collect_image_info timerfd_cinfo;
-extern struct restore_timerfd *rst_timerfd;
+
+int rst_timerfd_prep(void);
+extern unsigned long rst_timerfd_cpos;
 extern unsigned int rst_timerfd_nr;
 
-static inline unsigned long rst_timerfd_len(void)
-{
-	return sizeof(*rst_timerfd) * rst_timerfd_nr;
-}
 
 extern int check_timerfd(void);
 extern int is_timerfd_link(char *link);
diff --git a/timerfd.c b/timerfd.c
index cd15c09..79ddb2b 100644
--- a/timerfd.c
+++ b/timerfd.c
@@ -31,10 +31,14 @@ struct timerfd_dump_arg {
 struct timerfd_info {
 	TimerfdEntry		*tfe;
 	struct file_desc	d;
+	int			t_fd;
+	struct list_head	rlist;
 };
 
-struct restore_timerfd *rst_timerfd;
-unsigned int rst_timerfd_nr;
+static LIST_HEAD(rst_timerfds);
+
+unsigned long rst_timerfd_cpos;
+unsigned int rst_timerfd_nr = 0;
 
 int check_timerfd(void)
 {
@@ -105,24 +109,37 @@ const struct fdtype_ops timerfd_dump_ops = {
 static int timerfd_post_open(struct file_desc *d, int fd)
 {
 	struct timerfd_info *info = container_of(d, struct timerfd_info, d);
-	TimerfdEntry *tfe = info->tfe;
+
+	info->t_fd = fd;
+	list_add_tail(&info->rlist, &rst_timerfds);
+	return 0;
+}
+
+int rst_timerfd_prep(void)
+{
+	struct timerfd_info *ti;
 	struct restore_timerfd *t;
 
-	rst_timerfd_nr++;
-	rst_timerfd = xrealloc(rst_timerfd, rst_timerfd_len());
-	if (!rst_timerfd)
-		return -ENOMEM;
-
-	t = &rst_timerfd[rst_timerfd_nr - 1];
-	t->id				= tfe->id;
-	t->fd				= fd;
-	t->clockid			= tfe->clockid;
-	t->ticks			= (unsigned long)tfe->ticks;
-	t->settime_flags		= tfe->settime_flags;
-	t->val.it_interval.tv_sec	= (time_t)tfe->isec;
-	t->val.it_interval.tv_nsec	= (long)tfe->insec;
-	t->val.it_value.tv_sec		= (time_t)tfe->vsec;
-	t->val.it_value.tv_nsec		= (long)tfe->vnsec;
+	rst_timerfd_cpos = rst_mem_cpos(RM_PRIVATE);
+	list_for_each_entry(ti, &rst_timerfds, rlist) {
+		TimerfdEntry *tfe = ti->tfe;
+
+		t = rst_mem_alloc(sizeof(*t), RM_PRIVATE);
+		if (!t)
+			return -1;
+
+		t->id				= tfe->id;
+		t->fd				= ti->t_fd;
+		t->clockid			= tfe->clockid;
+		t->ticks			= (unsigned long)tfe->ticks;
+		t->settime_flags		= tfe->settime_flags;
+		t->val.it_interval.tv_sec	= (time_t)tfe->isec;
+		t->val.it_interval.tv_nsec	= (long)tfe->insec;
+		t->val.it_value.tv_sec		= (time_t)tfe->vsec;
+		t->val.it_value.tv_nsec		= (long)tfe->vnsec;
+
+		rst_timerfd_nr++;
+	}
 
 	return 0;
 }
@@ -186,6 +203,8 @@ static int collect_one_timerfd(void *o, ProtobufCMessage *msg)
 		return -1;
 	}
 
+	info->t_fd = -1;
+
 	return file_desc_add(&info->d, info->tfe->id, &timerfd_desc_ops);
 }
 
-- 
1.9.3




More information about the CRIU mailing list