From dfd5a62f38f6e6fe4a309d072e22203baa275db1 Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Tue, 15 Apr 2014 21:58:49 +0400 Subject: [PATCH] core: Move itimers on core This allows to have one image less per-task, which in turn reduces live migration time a little bit. Signed-off-by: Pavel Emelyanov --- cr-dump.c | 2 +- cr-restore.c | 23 ++++++++++++++++------- include/image-desc.h | 2 +- include/parasite-syscall.h | 2 +- parasite-syscall.c | 31 ++++++++++++------------------- protobuf/timer.proto | 3 +++ pstree.c | 12 ++++++++++-- 7 files changed, 44 insertions(+), 31 deletions(-) diff --git a/cr-dump.c b/cr-dump.c index 5e3371e99..4ae50e800 100644 --- a/cr-dump.c +++ b/cr-dump.c @@ -1525,7 +1525,7 @@ static int dump_one_task(struct pstree_item *item) goto err_cure; } - ret = parasite_dump_itimers_seized(parasite_ctl, cr_fdset); + ret = parasite_dump_itimers_seized(parasite_ctl, item); if (ret) { pr_err("Can't dump itimers (pid: %d)\n", pid); goto err_cure; diff --git a/cr-restore.c b/cr-restore.c index cd2f84713..45fdf69a5 100644 --- a/cr-restore.c +++ b/cr-restore.c @@ -1694,8 +1694,7 @@ static inline int timeval_valid(struct timeval *tv) return (tv->tv_sec >= 0) && ((unsigned long)tv->tv_usec < USEC_PER_SEC); } -static inline int itimer_restore_and_fix(char *n, ItimerEntry *ie, - struct itimerval *val) +static inline int decode_itimer(char *n, ItimerEntry *ie, struct itimerval *val) { if (ie->isec == 0 && ie->iusec == 0) { memzero_p(val); @@ -1734,11 +1733,21 @@ static inline int itimer_restore_and_fix(char *n, ItimerEntry *ie, return 0; } -static int prepare_itimers(int pid, struct task_restore_args *args) +static int prepare_itimers(int pid, CoreEntry *core, struct task_restore_args *args) { int fd, ret = -1; ItimerEntry *ie; + if (core->tc->timers) { + TaskTimersEntry *tte = core->tc->timers; + + ret = decode_itimer("real", tte->real, &args->itimers[0]); + ret |= decode_itimer("virt", tte->virt, &args->itimers[1]); + ret |= decode_itimer("prof", tte->prof, &args->itimers[2]); + + return ret; + } + fd = open_image(CR_FD_ITIMERS, O_RSTR, pid); if (fd < 0) return fd; @@ -1746,7 +1755,7 @@ static int prepare_itimers(int pid, struct task_restore_args *args) ret = pb_read_one(fd, &ie, PB_ITIMER); if (ret < 0) goto out; - ret = itimer_restore_and_fix("real", ie, &args->itimers[0]); + ret = decode_itimer("real", ie, &args->itimers[0]); itimer_entry__free_unpacked(ie, NULL); if (ret < 0) goto out; @@ -1754,7 +1763,7 @@ static int prepare_itimers(int pid, struct task_restore_args *args) ret = pb_read_one(fd, &ie, PB_ITIMER); if (ret < 0) goto out; - ret = itimer_restore_and_fix("virt", ie, &args->itimers[1]); + ret = decode_itimer("virt", ie, &args->itimers[1]); itimer_entry__free_unpacked(ie, NULL); if (ret < 0) goto out; @@ -1762,7 +1771,7 @@ static int prepare_itimers(int pid, struct task_restore_args *args) ret = pb_read_one(fd, &ie, PB_ITIMER); if (ret < 0) goto out; - ret = itimer_restore_and_fix("prof", ie, &args->itimers[2]); + ret = decode_itimer("prof", ie, &args->itimers[2]); itimer_entry__free_unpacked(ie, NULL); if (ret < 0) goto out; @@ -2488,7 +2497,7 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core) /* No longer need it */ core_entry__free_unpacked(core, NULL); - ret = prepare_itimers(pid, task_args); + ret = prepare_itimers(pid, core, task_args); if (ret < 0) goto err; diff --git a/include/image-desc.h b/include/image-desc.h index 84ad2c02a..d89081f1a 100644 --- a/include/image-desc.h +++ b/include/image-desc.h @@ -16,7 +16,6 @@ enum { CR_FD_IDS, CR_FD_MM, CR_FD_SIGACT, - CR_FD_ITIMERS, CR_FD_POSIX_TIMERS, CR_FD_CREDS, CR_FD_FS, @@ -86,6 +85,7 @@ enum { CR_FD_PAGES_OLD, CR_FD_SHM_PAGES_OLD, CR_FD_RLIMIT, + CR_FD_ITIMERS, CR_FD_IRMAP_CACHE, diff --git a/include/parasite-syscall.h b/include/parasite-syscall.h index 023d002e0..846c14f95 100644 --- a/include/parasite-syscall.h +++ b/include/parasite-syscall.h @@ -56,7 +56,7 @@ struct parasite_ctl { }; extern int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct cr_fdset *cr_fdset); -extern int parasite_dump_itimers_seized(struct parasite_ctl *ctl, struct cr_fdset *cr_fdset); +extern int parasite_dump_itimers_seized(struct parasite_ctl *ctl, struct pstree_item *); 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); diff --git a/parasite-syscall.c b/parasite-syscall.c index bb0cf3a09..e8ce30b84 100644 --- a/parasite-syscall.c +++ b/parasite-syscall.c @@ -604,22 +604,19 @@ int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct cr_fdset *cr_f return 0; } -static int dump_one_timer(struct itimerval *v, int fd) +static void encode_itimer(struct itimerval *v, ItimerEntry *ie) { - ItimerEntry ie = ITIMER_ENTRY__INIT; - - ie.isec = v->it_interval.tv_sec; - ie.iusec = v->it_interval.tv_usec; - ie.vsec = v->it_value.tv_sec; - ie.vusec = v->it_value.tv_usec; - - return pb_write_one(fd, &ie, PB_ITIMER); + ie->isec = v->it_interval.tv_sec; + ie->iusec = v->it_interval.tv_usec; + ie->vsec = v->it_value.tv_sec; + ie->vusec = v->it_value.tv_usec; } -int parasite_dump_itimers_seized(struct parasite_ctl *ctl, struct cr_fdset *cr_fdset) +int parasite_dump_itimers_seized(struct parasite_ctl *ctl, struct pstree_item *item) { + CoreEntry *core = item->core[0]; struct parasite_dump_itimers_args *args; - int ret, fd; + int ret; args = parasite_args(ctl, struct parasite_dump_itimers_args); @@ -627,15 +624,11 @@ int parasite_dump_itimers_seized(struct parasite_ctl *ctl, struct cr_fdset *cr_f if (ret < 0) return ret; - fd = fdset_fd(cr_fdset, CR_FD_ITIMERS); + encode_itimer(&args->real, core->tc->timers->real); + encode_itimer(&args->virt, core->tc->timers->virt); + encode_itimer(&args->prof, core->tc->timers->prof); - ret = dump_one_timer(&args->real, fd); - if (!ret) - ret = dump_one_timer(&args->virt, fd); - if (!ret) - ret = dump_one_timer(&args->prof, fd); - - return ret; + return 0; } static int dump_one_posix_timer(struct posix_timer *v, struct proc_posix_timer *vp, int fd) diff --git a/protobuf/timer.proto b/protobuf/timer.proto index b5852c3fb..9c0375047 100644 --- a/protobuf/timer.proto +++ b/protobuf/timer.proto @@ -20,4 +20,7 @@ message posix_timer_entry { } message task_timers_entry { + required itimer_entry real = 1; + required itimer_entry virt = 2; + required itimer_entry prof = 3; } diff --git a/pstree.c b/pstree.c index 33a97a863..c87b5dd4e 100644 --- a/pstree.c +++ b/pstree.c @@ -40,6 +40,7 @@ CoreEntry *core_entry_alloc(int th, int tsk) sz += RLIM_NLIMITS * sizeof(RlimitEntry *); sz += RLIM_NLIMITS * sizeof(RlimitEntry); sz += sizeof(TaskTimersEntry); + sz += 3 * sizeof(ItimerEntry); /* 3 for real, virt and prof */ } } if (th) @@ -59,6 +60,7 @@ CoreEntry *core_entry_alloc(int th, int tsk) if (th) { TaskRlimitsEntry *rls; + TaskTimersEntry *tte; int i; rls = xptr_pull(&m, TaskRlimitsEntry); @@ -73,8 +75,14 @@ CoreEntry *core_entry_alloc(int th, int tsk) rlimit_entry__init(rls->rlimits[i]); } - core->tc->timers = xptr_pull(&m, TaskTimersEntry); - task_timers_entry__init(core->tc->timers); + tte = core->tc->timers = xptr_pull(&m, TaskTimersEntry); + task_timers_entry__init(tte); + tte->real = xptr_pull(&m, ItimerEntry); + itimer_entry__init(tte->real); + tte->virt = xptr_pull(&m, ItimerEntry); + itimer_entry__init(tte->virt); + tte->prof = xptr_pull(&m, ItimerEntry); + itimer_entry__init(tte->prof); } }