git: 53d691cacae6 - stable/15 - reap_kill_subtree_once: when proctree_lock is dropped, reaper might change
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 13 Jun 2026 01:03:58 UTC
The branch stable/15 has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=53d691cacae602f96a80a656ec8f508b65ace81c
commit 53d691cacae602f96a80a656ec8f508b65ace81c
Author: Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2026-06-05 23:57:16 +0000
Commit: Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2026-06-13 00:58:38 +0000
reap_kill_subtree_once: when proctree_lock is dropped, reaper might change
(cherry picked from commit 44970244e6d872103f36eae34218b672b69579dd)
---
sys/kern/kern_procctl.c | 43 +++++++++++++++++++++++++++++--------------
1 file changed, 29 insertions(+), 14 deletions(-)
diff --git a/sys/kern/kern_procctl.c b/sys/kern/kern_procctl.c
index 1ff1b15767b5..c8d14aa2f2f6 100644
--- a/sys/kern/kern_procctl.c
+++ b/sys/kern/kern_procctl.c
@@ -49,6 +49,7 @@
#include <vm/pmap.h>
#include <vm/vm_map.h>
#include <vm/vm_extern.h>
+#include <vm/uma.h>
static int
protect_setchild(struct thread *td, struct proc *p, int flags)
@@ -366,13 +367,7 @@ reap_kill_sched(struct reap_kill_tracker_head *tracker, struct proc *p2)
{
struct reap_kill_tracker *t;
- PROC_LOCK(p2);
- if ((p2->p_flag2 & P2_WEXIT) != 0) {
- PROC_UNLOCK(p2);
- return;
- }
- _PHOLD(p2);
- PROC_UNLOCK(p2);
+ PROC_TREE_REF(p2);
t = malloc(sizeof(struct reap_kill_tracker), M_TEMP, M_WAITOK);
t->parent = p2;
TAILQ_INSERT_TAIL(tracker, t, link);
@@ -381,7 +376,7 @@ reap_kill_sched(struct reap_kill_tracker_head *tracker, struct proc *p2)
static void
reap_kill_sched_free(struct reap_kill_tracker *t)
{
- PRELE(t->parent);
+ PROC_TREE_UNREF(t->parent);
free(t, M_TEMP);
}
@@ -416,16 +411,17 @@ reap_kill_children(struct thread *td, struct proc *reaper,
}
static bool
-reap_kill_subtree_once(struct thread *td, struct proc *p, struct proc *reaper,
+reap_kill_subtree_once(struct thread *td, struct proc *p, struct proc **reaperp,
struct unrhdr *pids, struct reap_kill_proc_work *w)
{
struct reap_kill_tracker_head tracker;
struct reap_kill_tracker *t;
- struct proc *p2;
+ struct proc *p2, *reaper, *old_reaper;
bool proctree_dropped, res;
res = false;
TAILQ_INIT(&tracker);
+ reaper = *reaperp;
reap_kill_sched(&tracker, reaper);
while ((t = TAILQ_FIRST(&tracker)) != NULL) {
TAILQ_REMOVE(&tracker, t, link);
@@ -483,8 +479,24 @@ again:
}
PROC_UNLOCK(p2);
res = true;
- if (proctree_dropped)
+ if (proctree_dropped) {
+ old_reaper = reaper;
+ reaper = get_reaper_or_p(p);
+ if (old_reaper != reaper) {
+ *reaperp = reaper;
+ PROC_TREE_REF(reaper);
+ PROC_TREE_UNREF(old_reaper);
+ reap_kill_sched(&tracker, reaper);
+ /*
+ * Already scheduled kill
+ * actions should be kept on
+ * the schedule, the processes
+ * are inherited by the new
+ * reaper.
+ */
+ }
goto again;
+ }
}
reap_kill_sched_free(t);
}
@@ -492,7 +504,7 @@ again:
}
static void
-reap_kill_subtree(struct thread *td, struct proc *p, struct proc *reaper,
+reap_kill_subtree(struct thread *td, struct proc *p, struct proc **reaperp,
struct reap_kill_proc_work *w)
{
struct unrhdr pids;
@@ -512,7 +524,7 @@ reap_kill_subtree(struct thread *td, struct proc *p, struct proc *reaper,
goto out;
}
PROC_UNLOCK(td->td_proc);
- while (reap_kill_subtree_once(td, p, reaper, &pids, w))
+ while (reap_kill_subtree_once(td, p, reaperp, &pids, w))
;
ihandle = create_iter_unr(&pids);
@@ -562,6 +574,7 @@ reap_kill(struct thread *td, struct proc *p, void *data)
return (EINVAL);
PROC_UNLOCK(p);
reaper = get_reaper_or_p(p);
+
ksiginfo_init(&ksi);
ksi.ksi_signo = rk->rk_sig;
ksi.ksi_code = SI_USER;
@@ -577,7 +590,9 @@ reap_kill(struct thread *td, struct proc *p, void *data)
w.ksi = &ksi;
w.rk = rk;
w.error = &error;
- reap_kill_subtree(td, p, reaper, &w);
+ PROC_TREE_REF(reaper);
+ reap_kill_subtree(td, p, &reaper, &w);
+ PROC_TREE_UNREF(reaper);
crfree(w.cr);
}
PROC_LOCK(p);