The branch stable/13 has been updated by kib:

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

commit c35473f4ab3a58dcc2846713c131d6983d9ed009
Author:     Konstantin Belousov <k...@freebsd.org>
AuthorDate: 2021-04-13 13:47:24 +0000
Commit:     Konstantin Belousov <k...@freebsd.org>
CommitDate: 2021-04-23 11:14:09 +0000

    realtimer_expire: avoid proc lock recursion when called from 
itimer_proc_continue()
    
    (cherry picked from commit 5cc1d199412ead0b4c234e21e881a31ef893a4f0)
---
 sys/kern/kern_time.c | 24 +++++++++++++++++-------
 1 file changed, 17 insertions(+), 7 deletions(-)

diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c
index d3b19111b0f3..ab22ac4a1697 100644
--- a/sys/kern/kern_time.c
+++ b/sys/kern/kern_time.c
@@ -105,6 +105,7 @@ static int  realtimer_settime(struct itimer *, int,
 static int     realtimer_delete(struct itimer *);
 static void    realtimer_clocktime(clockid_t, struct timespec *);
 static void    realtimer_expire(void *);
+static void    realtimer_expire_l(struct itimer *it, bool proc_locked);
 
 static int     register_posix_clock(int, const struct kclock *);
 static void    itimer_fire(struct itimer *it);
@@ -919,7 +920,7 @@ itimer_proc_continue(struct proc *p)
                                if ((it->it_flags & ITF_PSTOPPED) != 0) {
                                        it->it_flags &= ~ITF_PSTOPPED;
                                        if ((it->it_flags & ITF_DELETING) == 0)
-                                               realtimer_expire(it);
+                                               realtimer_expire_l(it, true);
                                }
                                ITIMER_UNLOCK(it);
                        }
@@ -1663,18 +1664,14 @@ itimespecfix(struct timespec *ts)
        .tv_nsec = (ns) % 1000000000            \
 }
 
-/* Timeout callback for realtime timer */
 static void
-realtimer_expire(void *arg)
+realtimer_expire_l(struct itimer *it, bool proc_locked)
 {
        struct timespec cts, ts;
        struct timeval tv;
-       struct itimer *it;
        struct proc *p;
        uint64_t interval, now, overruns, value;
 
-       it = (struct itimer *)arg;
-
        realtimer_clocktime(it->it_clockid, &cts);
        /* Only fire if time is reached. */
        if (timespeccmp(&cts, &it->it_time.it_value, >=)) {
@@ -1708,8 +1705,9 @@ realtimer_expire(void *arg)
                        /* single shot timer ? */
                        timespecclear(&it->it_time.it_value);
                }
+
+               p = it->it_proc;
                if (timespecisset(&it->it_time.it_value)) {
-                       p = it->it_proc;
                        if (P_SHOULDSTOP(p) || P_KILLED(p)) {
                                it->it_flags |= ITF_PSTOPPED;
                        } else {
@@ -1719,9 +1717,14 @@ realtimer_expire(void *arg)
                                    realtimer_expire, it);
                        }
                }
+
                itimer_enter(it);
                ITIMER_UNLOCK(it);
+               if (proc_locked)
+                       PROC_UNLOCK(p);
                itimer_fire(it);
+               if (proc_locked)
+                       PROC_LOCK(p);
                ITIMER_LOCK(it);
                itimer_leave(it);
        } else if (timespecisset(&it->it_time.it_value)) {
@@ -1738,6 +1741,13 @@ realtimer_expire(void *arg)
        }
 }
 
+/* Timeout callback for realtime timer */
+static void
+realtimer_expire(void *arg)
+{
+       realtimer_expire_l(arg, false);
+}
+
 static void
 itimer_fire(struct itimer *it)
 {
_______________________________________________
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