The branch stable/13 has been updated by kib:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=6d608fc5ab9c6c8eedc85d739b4e58b21c16d19d

commit 6d608fc5ab9c6c8eedc85d739b4e58b21c16d19d
Author:     Konstantin Belousov <k...@freebsd.org>
AuthorDate: 2021-03-05 21:19:35 +0000
Commit:     Konstantin Belousov <k...@freebsd.org>
CommitDate: 2021-04-23 11:14:09 +0000

    Stop arming periodic process timers on suspend or terminate
    
    (cherry picked from commit dc47fdf1319f18be1aadbcdef17c721a83415d84)
---
 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 0b1305f49a93..f00aa57c95d2 100644
--- a/sys/kern/sys_process.c
+++ b/sys/kern/sys_process.c
@@ -1091,6 +1091,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 783c3896298c..c0cf0be7e7d7 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -813,6 +813,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 */
@@ -1079,6 +1080,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);
_______________________________________________
dev-commits-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all
To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"

Reply via email to