diff --git a/criu/cr-restore.c b/criu/cr-restore.c index 957478ce2..4e7bd5e79 100644 --- a/criu/cr-restore.c +++ b/criu/cr-restore.c @@ -3466,6 +3466,11 @@ static int sigreturn_restore(pid_t pid, struct task_restore_args *task_args, uns goto err; } + if (tcore->thread_core->has_timerslack_ns) { + thread_args[i].has_timerslack_ns = true; + thread_args[i].timerslack_ns = tcore->thread_core->timerslack_ns; + } + ret = prep_sched_info(&thread_args[i].sp, tcore->thread_core); if (ret) goto err; diff --git a/criu/include/restorer.h b/criu/include/restorer.h index 78da19182..5a141664c 100644 --- a/criu/include/restorer.h +++ b/criu/include/restorer.h @@ -114,6 +114,8 @@ struct thread_restore_args { unsigned int siginfo_n; int pdeath_sig; + bool has_timerslack_ns; + unsigned long timerslack_ns; struct thread_creds_args *creds_args; diff --git a/criu/pie/restorer.c b/criu/pie/restorer.c index 694a5e874..ee7b2c994 100644 --- a/criu/pie/restorer.c +++ b/criu/pie/restorer.c @@ -66,6 +66,10 @@ #define PR_SET_PDEATHSIG 1 #endif +#ifndef PR_SET_TIMERSLACK +#define PR_SET_TIMERSLACK 29 +#endif + #ifndef PR_SET_CHILD_SUBREAPER #define PR_SET_CHILD_SUBREAPER 36 #endif @@ -417,6 +421,22 @@ static inline int restore_pdeath_sig(struct thread_restore_args *ta) return 0; } +static inline int restore_timerslack(struct thread_restore_args *ta) +{ + int ret; + + if (!ta->has_timerslack_ns) + return 0; + + ret = sys_prctl(PR_SET_TIMERSLACK, ta->timerslack_ns, 0, 0, 0); + if (ret) { + pr_err("Unable to set PR_SET_TIMERSLACK(%lu): %d\n", ta->timerslack_ns, ret); + return -1; + } + + return 0; +} + static int restore_dumpable_flag(MmEntry *mme) { int current_dumpable; @@ -830,6 +850,7 @@ __visible long __export_restore_thread(struct thread_restore_args *args) ret = restore_creds(args->creds_args, args->ta->proc_fd, args->ta->lsm_type, args->ta->uid); ret = ret || restore_dumpable_flag(&args->ta->mm); ret = ret || restore_pdeath_sig(args); + ret = ret || restore_timerslack(args); if (ret) BUG(); @@ -2303,6 +2324,7 @@ __visible long __export_restore_task(struct task_restore_args *args) ret = restore_creds(args->t->creds_args, args->proc_fd, args->lsm_type, args->uid); ret = ret || restore_dumpable_flag(&args->mm); ret = ret || restore_pdeath_sig(args->t); + ret = ret || restore_timerslack(args->t); ret = ret || restore_child_subreaper(args->child_subreaper); atomic_set(&thread_inprogress, args->nr_threads);