The branch main has been updated by kib:

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

commit 0e67c3f675eab3a9c00b76e3886ace7700ef1bd4
Author:     Konstantin Belousov <[email protected]>
AuthorDate: 2026-02-16 15:20:02 +0000
Commit:     Konstantin Belousov <[email protected]>
CommitDate: 2026-02-21 09:45:47 +0000

    reap_kill_subtree_once(): reap_kill_proc_work() might drop proctree_lock
    
    Due to this, restart the iteration over the p_reapsiblings if the lock
    was dropped.
    
    Reviewed by:    markj
    Tested by:      pho
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D55288
---
 sys/kern/kern_procctl.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/sys/kern/kern_procctl.c b/sys/kern/kern_procctl.c
index 04c47d086677..30ab37d56877 100644
--- a/sys/kern/kern_procctl.c
+++ b/sys/kern/kern_procctl.c
@@ -280,7 +280,7 @@ reap_kill_proc_locked(struct reap_kill_proc_work *w)
 }
 
 static void
-reap_kill_proc(struct reap_kill_proc_work *w)
+reap_kill_proc(struct reap_kill_proc_work *w, bool *proctree_dropped)
 {
        struct pgrp *pgrp;
        int xlocked;
@@ -311,6 +311,7 @@ reap_kill_proc(struct reap_kill_proc_work *w)
                /* This is safe because pgrp zone is nofree. */
                sx_xlock(&pgrp->pg_killsx);
                sx_xunlock(&pgrp->pg_killsx);
+               *proctree_dropped = true;
                if (xlocked)
                        sx_xlock(&proctree_lock);
                else
@@ -392,7 +393,7 @@ reap_kill_subtree_once(struct thread *td, struct proc *p, 
struct proc *reaper,
        struct reap_kill_tracker_head tracker;
        struct reap_kill_tracker *t;
        struct proc *p2;
-       bool res;
+       bool proctree_dropped, res;
 
        res = false;
        TAILQ_INIT(&tracker);
@@ -400,6 +401,7 @@ reap_kill_subtree_once(struct thread *td, struct proc *p, 
struct proc *reaper,
        while ((t = TAILQ_FIRST(&tracker)) != NULL) {
                TAILQ_REMOVE(&tracker, t, link);
 
+again:
                /*
                 * Since reap_kill_proc() drops proctree_lock sx, it
                 * is possible that the tracked reaper is no longer.
@@ -435,6 +437,7 @@ reap_kill_subtree_once(struct thread *td, struct proc *p, 
struct proc *reaper,
                            (P2_REAPKILLED | P2_WEXIT)) != 0)
                                continue;
 
+                       proctree_dropped = false;
                        PROC_LOCK(p2);
                        if ((p2->p_flag2 & P2_WEXIT) == 0) {
                                _PHOLD(p2);
@@ -446,11 +449,13 @@ reap_kill_subtree_once(struct thread *td, struct proc *p, 
struct proc *reaper,
                                p2->p_flag2 |= P2_REAPKILLED;
 
                                w->target = p2;
-                               reap_kill_proc(w);
+                               reap_kill_proc(w, &proctree_dropped);
                                _PRELE(p2);
                        }
                        PROC_UNLOCK(p2);
                        res = true;
+                       if (proctree_dropped)
+                               goto again;
                }
                reap_kill_sched_free(t);
        }

Reply via email to