Date: Fri, 9 Apr 2021 20:44:32 GMT From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: dc47fdf1319f - main - Stop arming periodic process timers on suspend or terminate Message-ID: <202104092044.139KiWv5070966@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=dc47fdf1319f18be1aadbcdef17c721a83415d84 commit dc47fdf1319f18be1aadbcdef17c721a83415d84 Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2021-03-05 21:19:35 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2021-04-09 20:42:44 +0000 Stop arming periodic process timers on suspend or terminate Reported and reviewed by: markj Tested by: markj, pho Sponsored by: The FreeBSD Foundation MFC after: 2 weeks Differential revision: https://reviews.freebsd.org/D29106 --- sys/kern/kern_sig.c | 6 ++++-- sys/kern/kern_time.c | 38 ++++++++++++++++++++++++++++++++++++-- sys/kern/sys_process.c | 1 + sys/sys/proc.h | 2 ++ 4 files changed, 43 insertions(+), 4 deletions(-) diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 3d55405d3151..212b4997dd5e 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -2322,7 +2322,7 @@ tdsendsignal(struct proc *p, struct thread *td, int sig, ksiginfo_t *ksi) thread_unsuspend(p); PROC_SUNLOCK(p); sigqueue_delete(sigqueue, sig); - goto out; + goto out_cont; } if (action == SIG_CATCH) { /* @@ -2337,7 +2337,7 @@ tdsendsignal(struct proc *p, struct thread *td, int sig, ksiginfo_t *ksi) */ thread_unsuspend(p); PROC_SUNLOCK(p); - goto out; + goto out_cont; } if (prop & SIGPROP_STOP) { @@ -2422,6 +2422,8 @@ runfast: PROC_SLOCK(p); thread_unsuspend(p); PROC_SUNLOCK(p); +out_cont: + itimer_proc_continue(p); out: /* If we jump here, proc slock should not be owned. */ PROC_SLOCK_ASSERT(p, MA_NOTOWNED); diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c index 44f6b4ad07f2..3010ee326105 100644 --- a/sys/kern/kern_time.c +++ b/sys/kern/kern_time.c @@ -881,6 +881,33 @@ kern_setitimer(struct thread *td, u_int which, struct itimerval *aitv, return (0); } +static void +realitexpire_reset_callout(struct proc *p, sbintime_t *isbtp) +{ + sbintime_t prec; + + prec = isbtp == NULL ? tvtosbt(p->p_realtimer.it_interval) : *isbtp; + callout_reset_sbt(&p->p_itcallout, tvtosbt(p->p_realtimer.it_value), + prec >> tc_precexp, realitexpire, p, C_ABSOLUTE); +} + +void +itimer_proc_continue(struct proc *p) +{ + struct timeval ctv; + + PROC_LOCK_ASSERT(p, MA_OWNED); + + if ((p->p_flag2 & P2_ITSTOPPED) != 0) { + p->p_flag2 &= ~P2_ITSTOPPED; + microuptime(&ctv); + if (timevalcmp(&p->p_realtimer.it_value, &ctv, >=)) + realitexpire(p); + else + realitexpire_reset_callout(p, NULL); + } +} + /* * Real interval timer expired: * send process whose timer expired an alarm signal. @@ -908,6 +935,7 @@ realitexpire(void *arg) wakeup(&p->p_itcallout); return; } + isbt = tvtosbt(p->p_realtimer.it_interval); if (isbt >= sbt_timethreshold) getmicrouptime(&ctv); @@ -917,8 +945,14 @@ realitexpire(void *arg) timevaladd(&p->p_realtimer.it_value, &p->p_realtimer.it_interval); } while (timevalcmp(&p->p_realtimer.it_value, &ctv, <=)); - callout_reset_sbt(&p->p_itcallout, tvtosbt(p->p_realtimer.it_value), - isbt >> tc_precexp, realitexpire, p, C_ABSOLUTE); + + if (P_SHOULDSTOP(p) || P_KILLED(p)) { + p->p_flag2 |= P2_ITSTOPPED; + return; + } + + p->p_flag2 &= ~P2_ITSTOPPED; + realitexpire_reset_callout(p, &isbt); } /* diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c index 3a184f1d678f..8c0f743aef8a 100644 --- a/sys/kern/sys_process.c +++ b/sys/kern/sys_process.c @@ -1094,6 +1094,7 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data) p->p_flag &= ~(P_STOPPED_TRACE | P_STOPPED_SIG | P_WAITED); thread_unsuspend(p); PROC_SUNLOCK(p); + itimer_proc_continue(p); break; case PT_WRITE_I: diff --git a/sys/sys/proc.h b/sys/sys/proc.h index d51ad1093833..8d41b9b20f10 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -825,6 +825,7 @@ struct proc { MAP_STACK */ #define P2_STKGAP_DISABLE_EXEC 0x00001000 /* Stack gap disabled after exec */ +#define P2_ITSTOPPED 0x00002000 /* Flags protected by proctree_lock, kept in p_treeflags. */ #define P_TREE_ORPHANED 0x00000001 /* Reparented, on orphan list */ @@ -1091,6 +1092,7 @@ void fork_exit(void (*)(void *, struct trapframe *), void *, struct trapframe *); void fork_return(struct thread *, struct trapframe *); int inferior(struct proc *p); +void itimer_proc_continue(struct proc *p); void kern_proc_vmmap_resident(struct vm_map *map, struct vm_map_entry *entry, int *resident_count, bool *super); void kern_yield(int);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202104092044.139KiWv5070966>