[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