git: 0e67c3f675ea - main - reap_kill_subtree_once(): reap_kill_proc_work() might drop proctree_lock
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 21 Feb 2026 10:07:57 UTC
The branch main has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=0e67c3f675eab3a9c00b76e3886ace7700ef1bd4
commit 0e67c3f675eab3a9c00b76e3886ace7700ef1bd4
Author: Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2026-02-16 15:20:02 +0000
Commit: Konstantin Belousov <kib@FreeBSD.org>
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);
}