Commit d9a9d4c9 authored by Pavel Emelyanov's avatar Pavel Emelyanov

rst: Fix timerfd rst memory management

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: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 73e303c8
......@@ -2647,9 +2647,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;
......@@ -2724,11 +2721,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
......@@ -2876,7 +2870,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);
......
......@@ -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);
......
......@@ -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);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment