From nobody Sat Feb 28 01:33:16 2026 X-Original-To: dev-commits-src-branches@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4fN74X2KWyz6Tnxq for ; Sat, 28 Feb 2026 01:33:16 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R12" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4fN74X0qWnz47dm for ; Sat, 28 Feb 2026 01:33:16 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1772242396; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=IxlNTudpjl+yWUNZFCgA1Glqkod9+8hZrHKlZ/W0owc=; b=MtLShUpjsbnm2Q/AcpBgpA5zHslgI/i2TfIuQt3wUWErJk3B+SiCf8adzO3CpC2qUv/+u/ HKoEq9TTY5WPGsbJOTsgU/4yYucLscuob4FZUqk2ymDYj7aVp536d4kDWAw36kdBGi9Hvx Zxp0s688dLxv+zmrE+EcznYnH7fWCXyknQnCwP7r3qLAJBWXGdc6pUxaIr7xnSgh7qbdpe T/vnmh+++OxVfYgP8/Y5haJKpNLXuZNyfKtz8C8buHc5Dz8OWE2arSBHG3+StECMUk+8+W s4kBnTAgIpFqKeJmRVkzHRRky2f9NzUDXeyiGSczNkYhkAvmN7C0f48Gh6jmHQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1772242396; a=rsa-sha256; cv=none; b=ql08Mc+dPo8MhTIs6yaUGKPL6QTHPjwmo9MlGL0pCeg+55Qge+Arf7pMKgWrcoQ3/X/xOS huv0ZAlg8Yzw4lzWs9K0VLr/Rc6GT17SCuB3wvDlujpVf4Cs+vMq3wWM/0fyRHvhkDNMyk j3j1XIuko0uCoXtfrM/PHBwp6FfiRTGgDCkgXA1C6l8tqW6bGJRSN7A6JH0rRCYGnU5ysE HGjeM7P2V/H+cW3LVvFepAA+JR85toB50NQOceGKsVxi0YqW+TewJU4emlGGtN7XUB3o7A N5GNf0nCt7YlJaqI1xiKb5Mn32olppcg4gWIBNhdywQflvZRGqJH1kEYQEw33w== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1772242396; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=IxlNTudpjl+yWUNZFCgA1Glqkod9+8hZrHKlZ/W0owc=; b=Q44mcdwOUABS/FSE+lhVFkgN33+yxzT75D4g1yC3hHp47vLDI57KEj98cLvIcyfOpCUunk 4ByyPMKcwo9hIlgGN3fsmZBQd+ZjQhV4PD0PCkuL6JPduHb7SLSidXRM/07/Jx3GL4fEXo 2N6Lln1bHilyuvdhr7mezw+oCxxdw6JtVpfNgnw4A33+0k2mtSVqHo3rjxt/09OQ5+A5CW J2WDEVXutvDpUdDMkkwaf3ds4BUxE6MVuVCdYUX0zH4tg55/8xcxEeyEMGn4q3ridyoHeG SHEVwU5130yOBpQjaBtNb87yvpItW8DvYQzaflEGF7JDF9G2VuIGsMQ8DsqY4g== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4fN74X0Qb4zjdn for ; Sat, 28 Feb 2026 01:33:16 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 19cd9 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sat, 28 Feb 2026 01:33:16 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Konstantin Belousov Subject: git: 08f95c4938d3 - stable/15 - procctl(PROC_REAP_KILL): use pgrp pg_killsx sx to sync with fork List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-branches@freebsd.org Sender: owner-dev-commits-src-branches@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kib X-Git-Repository: src X-Git-Refname: refs/heads/stable/15 X-Git-Reftype: branch X-Git-Commit: 08f95c4938d301a9e00e69b97d1dea3cacd98ac5 Auto-Submitted: auto-generated Date: Sat, 28 Feb 2026 01:33:16 +0000 Message-Id: <69a245dc.19cd9.310916a9@gitrepo.freebsd.org> The branch stable/15 has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=08f95c4938d301a9e00e69b97d1dea3cacd98ac5 commit 08f95c4938d301a9e00e69b97d1dea3cacd98ac5 Author: Konstantin Belousov AuthorDate: 2026-02-15 11:05:36 +0000 Commit: Konstantin Belousov CommitDate: 2026-02-28 01:32:24 +0000 procctl(PROC_REAP_KILL): use pgrp pg_killsx sx to sync with fork PR: 290844 (cherry picked from commit be140717a0a4bbfa7176d334c36364d34a0b1bc5) --- sys/kern/kern_procctl.c | 142 +++++++++++++++++++----------------------------- 1 file changed, 56 insertions(+), 86 deletions(-) diff --git a/sys/kern/kern_procctl.c b/sys/kern/kern_procctl.c index 96365e192d3c..04c47d086677 100644 --- a/sys/kern/kern_procctl.c +++ b/sys/kern/kern_procctl.c @@ -43,7 +43,6 @@ #include #include #include -#include #include #include @@ -256,68 +255,73 @@ struct reap_kill_proc_work { ksiginfo_t *ksi; struct procctl_reaper_kill *rk; int *error; - struct task t; }; static void reap_kill_proc_locked(struct reap_kill_proc_work *w) { - int error1; - bool need_stop; + int error; PROC_LOCK_ASSERT(w->target, MA_OWNED); PROC_ASSERT_HELD(w->target); - error1 = cr_cansignal(w->cr, w->target, w->rk->rk_sig); - if (error1 != 0) { + error = cr_cansignal(w->cr, w->target, w->rk->rk_sig); + if (error != 0) { if (*w->error == ESRCH) { w->rk->rk_fpid = w->target->p_pid; - *w->error = error1; + *w->error = error; } return; } - /* - * The need_stop indicates if the target process needs to be - * suspended before being signalled. This is needed when we - * guarantee that all processes in subtree are signalled, - * avoiding the race with some process not yet fully linked - * into all structures during fork, ignored by iterator, and - * then escaping signalling. - * - * The thread cannot usefully stop itself anyway, and if other - * thread of the current process forks while the current - * thread signals the whole subtree, it is an application - * race. - */ - if ((w->target->p_flag & (P_KPROC | P_SYSTEM | P_STOPPED)) == 0) - need_stop = thread_single(w->target, SINGLE_ALLPROC) == 0; - else - need_stop = false; - (void)pksignal(w->target, w->rk->rk_sig, w->ksi); w->rk->rk_killed++; - *w->error = error1; - - if (need_stop) - thread_single_end(w->target, SINGLE_ALLPROC); + *w->error = error; } static void -reap_kill_proc_work(void *arg, int pending __unused) +reap_kill_proc(struct reap_kill_proc_work *w) { - struct reap_kill_proc_work *w; - - w = arg; - PROC_LOCK(w->target); - if ((w->target->p_flag2 & P2_WEXIT) == 0) - reap_kill_proc_locked(w); - PROC_UNLOCK(w->target); - - sx_xlock(&proctree_lock); - w->target = NULL; - wakeup(&w->target); - sx_xunlock(&proctree_lock); + struct pgrp *pgrp; + int xlocked; + + sx_assert(&proctree_lock, SX_LOCKED); + xlocked = sx_xlocked(&proctree_lock); + PROC_LOCK_ASSERT(w->target, MA_OWNED); + PROC_ASSERT_HELD(w->target); + + /* Sync with forks. */ + for (;;) { + /* + * Short-circuit handling of the exiting process, do + * not wait for it to single-thread (hold prevents it + * from exiting further). This avoids + * locking pg_killsx for it, and reduces the + * proctree_lock contention. + */ + if ((w->target->p_flag2 & P2_WEXIT) != 0) + return; + + pgrp = w->target->p_pgrp; + if (pgrp == NULL || sx_try_xlock(&pgrp->pg_killsx)) + break; + + PROC_UNLOCK(w->target); + sx_unlock(&proctree_lock); + /* This is safe because pgrp zone is nofree. */ + sx_xlock(&pgrp->pg_killsx); + sx_xunlock(&pgrp->pg_killsx); + if (xlocked) + sx_xlock(&proctree_lock); + else + sx_slock(&proctree_lock); + PROC_LOCK(w->target); + } + + reap_kill_proc_locked(w); + + if (pgrp != NULL) + sx_xunlock(&pgrp->pg_killsx); } struct reap_kill_tracker { @@ -388,8 +392,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; - int r, xlocked; - bool res, st; + bool res; res = false; TAILQ_INIT(&tracker); @@ -432,53 +435,21 @@ reap_kill_subtree_once(struct thread *td, struct proc *p, struct proc *reaper, (P2_REAPKILLED | P2_WEXIT)) != 0) continue; - if (p2 == td->td_proc) { - if ((p2->p_flag & P_HADTHREADS) != 0 && - (p2->p_flag2 & P2_WEXIT) == 0) { - xlocked = sx_xlocked(&proctree_lock); - sx_unlock(&proctree_lock); - st = true; - } else { - st = false; - } - PROC_LOCK(p2); + PROC_LOCK(p2); + if ((p2->p_flag2 & P2_WEXIT) == 0) { + _PHOLD(p2); + /* * sapblk ensures that only one thread * in the system sets this flag. */ p2->p_flag2 |= P2_REAPKILLED; - if (st) - r = thread_single(p2, SINGLE_NO_EXIT); - (void)pksignal(p2, w->rk->rk_sig, w->ksi); - w->rk->rk_killed++; - if (st && r == 0) - thread_single_end(p2, SINGLE_NO_EXIT); - PROC_UNLOCK(p2); - if (st) { - if (xlocked) - sx_xlock(&proctree_lock); - else - sx_slock(&proctree_lock); - } - } else { - PROC_LOCK(p2); - if ((p2->p_flag2 & P2_WEXIT) == 0) { - _PHOLD(p2); - p2->p_flag2 |= P2_REAPKILLED; - PROC_UNLOCK(p2); - w->target = p2; - taskqueue_enqueue(taskqueue_thread, - &w->t); - while (w->target != NULL) { - sx_sleep(&w->target, - &proctree_lock, PWAIT, - "reapst", 0); - } - PROC_LOCK(p2); - _PRELE(p2); - } - PROC_UNLOCK(p2); + + w->target = p2; + reap_kill_proc(w); + _PRELE(p2); } + PROC_UNLOCK(p2); res = true; } reap_kill_sched_free(t); @@ -572,7 +543,6 @@ reap_kill(struct thread *td, struct proc *p, void *data) w.ksi = &ksi; w.rk = rk; w.error = &error; - TASK_INIT(&w.t, 0, reap_kill_proc_work, &w); reap_kill_subtree(td, p, reaper, &w); crfree(w.cr); }