Commit b54e3409 authored by Pavel Emelyanov's avatar Pavel Emelyanov

core: Move posix timers on core entry

This as well gives us minus one image per-task and
allocates more space on core task entry.

One thing to note -- the amount of posix timers is
not easily accessible at the core entry allocation
time, so the respective array is allocated on demand.
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent dfd5a62f
...@@ -1531,7 +1531,7 @@ static int dump_one_task(struct pstree_item *item) ...@@ -1531,7 +1531,7 @@ static int dump_one_task(struct pstree_item *item)
goto err_cure; goto err_cure;
} }
ret = parasite_dump_posix_timers_seized(&proc_args, parasite_ctl, cr_fdset); ret = parasite_dump_posix_timers_seized(&proc_args, parasite_ctl, item);
if (ret) { if (ret) {
pr_err("Can't dump posix timers (pid: %d)\n", pid); pr_err("Can't dump posix timers (pid: %d)\n", pid);
goto err_cure; goto err_cure;
......
...@@ -87,7 +87,7 @@ static int restore_task_with_children(void *); ...@@ -87,7 +87,7 @@ static int restore_task_with_children(void *);
static int sigreturn_restore(pid_t pid, CoreEntry *core); static int sigreturn_restore(pid_t pid, CoreEntry *core);
static int prepare_restorer_blob(void); static int prepare_restorer_blob(void);
static int prepare_rlimits(int pid, CoreEntry *core); static int prepare_rlimits(int pid, CoreEntry *core);
static int prepare_posix_timers(int pid); static int prepare_posix_timers(int pid, CoreEntry *core);
static int prepare_signals(int pid); static int prepare_signals(int pid);
static int shmem_remap(void *old_addr, void *new_addr, unsigned long size) static int shmem_remap(void *old_addr, void *new_addr, unsigned long size)
...@@ -713,7 +713,7 @@ static int restore_one_alive_task(int pid, CoreEntry *core) ...@@ -713,7 +713,7 @@ static int restore_one_alive_task(int pid, CoreEntry *core)
if (prepare_signals(pid)) if (prepare_signals(pid))
return -1; return -1;
if (prepare_posix_timers(pid)) if (prepare_posix_timers(pid, core))
return -1; return -1;
if (prepare_rlimits(pid, core) < 0) if (prepare_rlimits(pid, core) < 0)
...@@ -1785,7 +1785,7 @@ static inline int timespec_valid(struct timespec *ts) ...@@ -1785,7 +1785,7 @@ static inline int timespec_valid(struct timespec *ts)
return (ts->tv_sec >= 0) && ((unsigned long)ts->tv_nsec < NSEC_PER_SEC); return (ts->tv_sec >= 0) && ((unsigned long)ts->tv_nsec < NSEC_PER_SEC);
} }
static inline int posix_timer_restore_and_fix(PosixTimerEntry *pte, static inline int decode_posix_timer(PosixTimerEntry *pte,
struct restore_posix_timer *pt) struct restore_posix_timer *pt)
{ {
pt->val.it_interval.tv_sec = pte->isec; pt->val.it_interval.tv_sec = pte->isec;
...@@ -1829,13 +1829,32 @@ static int cmp_posix_timer_proc_id(const void *p1, const void *p2) ...@@ -1829,13 +1829,32 @@ static int cmp_posix_timer_proc_id(const void *p1, const void *p2)
static unsigned long posix_timers_cpos; static unsigned long posix_timers_cpos;
static unsigned int posix_timers_nr; static unsigned int posix_timers_nr;
static int prepare_posix_timers(int pid) static int prepare_posix_timers(int pid, CoreEntry *core)
{ {
int fd; int fd = -1;
int ret = -1; int ret = -1;
struct restore_posix_timer *t; struct restore_posix_timer *t;
posix_timers_cpos = rst_mem_cpos(RM_PRIVATE); posix_timers_cpos = rst_mem_cpos(RM_PRIVATE);
if (core->tc->timers) {
int i;
TaskTimersEntry *tte = core->tc->timers;
posix_timers_nr = tte->n_posix;
for (i = 0; i < posix_timers_nr; i++) {
t = rst_mem_alloc(sizeof(struct restore_posix_timer), RM_PRIVATE);
if (!t)
goto out;
if (decode_posix_timer(tte->posix[i], t))
goto out;
}
ret = 0;
goto out;
}
fd = open_image(CR_FD_POSIX_TIMERS, O_RSTR, pid); fd = open_image(CR_FD_POSIX_TIMERS, O_RSTR, pid);
if (fd < 0) { if (fd < 0) {
if (errno == ENOENT) /* backward compatibility */ if (errno == ENOENT) /* backward compatibility */
...@@ -1856,7 +1875,7 @@ static int prepare_posix_timers(int pid) ...@@ -1856,7 +1875,7 @@ static int prepare_posix_timers(int pid)
if (!t) if (!t)
goto out; goto out;
ret = posix_timer_restore_and_fix(pte, t); ret = decode_posix_timer(pte, t);
if (ret < 0) if (ret < 0)
goto out; goto out;
......
...@@ -16,7 +16,6 @@ enum { ...@@ -16,7 +16,6 @@ enum {
CR_FD_IDS, CR_FD_IDS,
CR_FD_MM, CR_FD_MM,
CR_FD_SIGACT, CR_FD_SIGACT,
CR_FD_POSIX_TIMERS,
CR_FD_CREDS, CR_FD_CREDS,
CR_FD_FS, CR_FD_FS,
CR_FD_SIGNAL, CR_FD_SIGNAL,
...@@ -86,6 +85,7 @@ enum { ...@@ -86,6 +85,7 @@ enum {
CR_FD_SHM_PAGES_OLD, CR_FD_SHM_PAGES_OLD,
CR_FD_RLIMIT, CR_FD_RLIMIT,
CR_FD_ITIMERS, CR_FD_ITIMERS,
CR_FD_POSIX_TIMERS,
CR_FD_IRMAP_CACHE, CR_FD_IRMAP_CACHE,
......
...@@ -59,7 +59,8 @@ extern int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct cr_fdse ...@@ -59,7 +59,8 @@ extern int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct cr_fdse
extern int parasite_dump_itimers_seized(struct parasite_ctl *ctl, struct pstree_item *); extern int parasite_dump_itimers_seized(struct parasite_ctl *ctl, struct pstree_item *);
struct proc_posix_timers_stat; struct proc_posix_timers_stat;
extern int parasite_dump_posix_timers_seized(struct proc_posix_timers_stat *proc_args, struct parasite_ctl *ctl, struct cr_fdset *cr_fdset); extern int parasite_dump_posix_timers_seized(struct proc_posix_timers_stat *proc_args,
struct parasite_ctl *ctl, struct pstree_item *);
#define parasite_args(ctl, type) \ #define parasite_args(ctl, type) \
({ \ ({ \
......
...@@ -631,33 +631,55 @@ int parasite_dump_itimers_seized(struct parasite_ctl *ctl, struct pstree_item *i ...@@ -631,33 +631,55 @@ int parasite_dump_itimers_seized(struct parasite_ctl *ctl, struct pstree_item *i
return 0; return 0;
} }
static int dump_one_posix_timer(struct posix_timer *v, struct proc_posix_timer *vp, int fd) static void encode_posix_timer(struct posix_timer *v, struct proc_posix_timer *vp, PosixTimerEntry *pte)
{ {
PosixTimerEntry pte = POSIX_TIMER_ENTRY__INIT; pte->it_id = vp->spt.it_id;
pte->clock_id = vp->spt.clock_id;
pte->si_signo = vp->spt.si_signo;
pte->it_sigev_notify = vp->spt.it_sigev_notify;
pte->sival_ptr = encode_pointer(vp->spt.sival_ptr);
pte->overrun = v->overrun;
pte->isec = v->val.it_interval.tv_sec;
pte->insec = v->val.it_interval.tv_nsec;
pte->vsec = v->val.it_value.tv_sec;
pte->vnsec = v->val.it_value.tv_nsec;
}
pte.it_id = vp->spt.it_id; static int core_alloc_posix_timers(TaskTimersEntry *tte, int n,
pte.clock_id = vp->spt.clock_id; PosixTimerEntry **pte)
pte.si_signo = vp->spt.si_signo; {
pte.it_sigev_notify = vp->spt.it_sigev_notify; int sz;
pte.sival_ptr = encode_pointer(vp->spt.sival_ptr);
pte.overrun = v->overrun; /*
* Will be free()-ed in core_entry_free()
*/
pte.isec = v->val.it_interval.tv_sec; sz = n * (sizeof(PosixTimerEntry *) + sizeof(PosixTimerEntry));
pte.insec = v->val.it_interval.tv_nsec; tte->posix = xmalloc(sz);
pte.vsec = v->val.it_value.tv_sec; if (!tte->posix)
pte.vnsec = v->val.it_value.tv_nsec; return -1;
return pb_write_one(fd, &pte, PB_POSIX_TIMER); tte->n_posix = n;
*pte = (PosixTimerEntry *)(tte->posix + n);
return 0;
} }
int parasite_dump_posix_timers_seized(struct proc_posix_timers_stat *proc_args, struct parasite_ctl *ctl, struct cr_fdset *cr_fdset) int parasite_dump_posix_timers_seized(struct proc_posix_timers_stat *proc_args,
struct parasite_ctl *ctl, struct pstree_item *item)
{ {
CoreEntry *core = item->core[0];
TaskTimersEntry *tte = core->tc->timers;
PosixTimerEntry *pte;
struct parasite_dump_posix_timers_args * args; struct parasite_dump_posix_timers_args * args;
struct proc_posix_timer *temp; struct proc_posix_timer *temp;
int i, fd; int i;
int ret = 0; int ret = 0;
if (core_alloc_posix_timers(tte, proc_args->timer_n, &pte))
return -1;
args = parasite_args_s(ctl, posix_timers_dump_size(proc_args->timer_n)); args = parasite_args_s(ctl, posix_timers_dump_size(proc_args->timer_n));
args->timer_n = proc_args->timer_n; args->timer_n = proc_args->timer_n;
...@@ -671,14 +693,12 @@ int parasite_dump_posix_timers_seized(struct proc_posix_timers_stat *proc_args, ...@@ -671,14 +693,12 @@ int parasite_dump_posix_timers_seized(struct proc_posix_timers_stat *proc_args,
if (ret < 0) if (ret < 0)
goto end_posix; goto end_posix;
fd = fdset_fd(cr_fdset, CR_FD_POSIX_TIMERS);
i = 0; i = 0;
list_for_each_entry(temp, &proc_args->timers, list) { list_for_each_entry(temp, &proc_args->timers, list) {
ret = dump_one_posix_timer(&args->timer[i], temp, fd); posix_timer_entry__init(&pte[i]);
encode_posix_timer(&args->timer[i], temp, &pte[i]);
tte->posix[i] = &pte[i];
i++; i++;
if (ret)
goto end_posix;
} }
end_posix: end_posix:
...@@ -687,6 +707,7 @@ end_posix: ...@@ -687,6 +707,7 @@ end_posix:
list_del(&temp->list); list_del(&temp->list);
xfree(temp); xfree(temp);
} }
return ret; return ret;
} }
......
...@@ -23,4 +23,5 @@ message task_timers_entry { ...@@ -23,4 +23,5 @@ message task_timers_entry {
required itimer_entry real = 1; required itimer_entry real = 1;
required itimer_entry virt = 2; required itimer_entry virt = 2;
required itimer_entry prof = 3; required itimer_entry prof = 3;
repeated posix_timer_entry posix = 4;
} }
...@@ -18,6 +18,8 @@ struct pstree_item *root_item; ...@@ -18,6 +18,8 @@ struct pstree_item *root_item;
void core_entry_free(CoreEntry *core) void core_entry_free(CoreEntry *core)
{ {
if (core->tc && core->tc->timers)
xfree(core->tc->timers->posix);
arch_free_thread_info(core); arch_free_thread_info(core);
xfree(core); xfree(core);
} }
......
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