aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/kern_procctl.c
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2022-05-15 22:52:09 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2022-06-24 14:45:46 +0000
commitb18df35be04213e6a603b54d404215a923fe66e2 (patch)
treeb912db3318b72c7279bc85c4590d64b6a585d480 /sys/kern/kern_procctl.c
parent935509ba185d9c2781fad2bc6bb8ec77a2534a78 (diff)
reap_kill_subtree(): hold the reaper when entering it into the queue to handle later
(cherry picked from commit e0343eacf36588bf503c7a59c0cc436294223839)
Diffstat (limited to 'sys/kern/kern_procctl.c')
-rw-r--r--sys/kern/kern_procctl.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/sys/kern/kern_procctl.c b/sys/kern/kern_procctl.c
index 02469f25bc3d..b32a4156dafb 100644
--- a/sys/kern/kern_procctl.c
+++ b/sys/kern/kern_procctl.c
@@ -336,12 +336,26 @@ 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_LITE(p2);
+ PROC_UNLOCK(p2);
t = malloc(sizeof(struct reap_kill_tracker), M_TEMP, M_WAITOK);
t->parent = p2;
TAILQ_INSERT_TAIL(tracker, t, link);
}
static void
+reap_kill_sched_free(struct reap_kill_tracker *t)
+{
+ PRELE(t->parent);
+ free(t, M_TEMP);
+}
+
+static void
reap_kill_children(struct thread *td, struct proc *reaper,
struct procctl_reaper_kill *rk, ksiginfo_t *ksi, int *error)
{
@@ -379,7 +393,7 @@ reap_kill_subtree_once(struct thread *td, struct proc *p, struct proc *reaper,
* reaper, which should handle it.
*/
if ((t->parent->p_treeflag & P_TREE_REAPER) == 0) {
- free(t, M_TEMP);
+ reap_kill_sched_free(t);
res = true;
continue;
}
@@ -396,7 +410,7 @@ reap_kill_subtree_once(struct thread *td, struct proc *p, struct proc *reaper,
reap_kill_proc(td, p2, ksi, rk, error);
res = true;
}
- free(t, M_TEMP);
+ reap_kill_sched_free(t);
}
return (res);
}