From nobody Sat Sep 03 01:29:24 2022 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 4MKHJ43nl1z4bw8N; Sat, 3 Sep 2022 01:29:24 +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 "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4MKHJ41pTTz3NHF; Sat, 3 Sep 2022 01:29:24 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1662168564; 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=QRwSYD7/gEEpyCwlz/xyQ6nrTBvmPByj8g9tEgchNwo=; b=OUgekLftgIkmxT0XCGotDqkU4vCwtnbp81D0lONCD1sDPBrmuXJ2IedCNq4uPXqEi/6WwZ 6ma1dr5pGKkzdLo1x0WPJ7ENZow28iBfP+F0K3RyXawGugBf4WHkEyj1vw69rnCSvn8DCM Xi8Sr2cFpiiMW76/kzjSrpBLoRMgnSWZGvERtKcDXlaznxb2GAnramDZW3+Vf6IbCLSdsq BzBvjTkVhhEpd84eCMKdAAWaCQerqvFCCCVj3Pawpml+GuLL+rqpUzUiEDKNrf3HIV3BYb nr/yeUm+no0jZJ2+zmfp549/8m5LJ9/1SdP/9tE4noxz7B0+xI4qCP4tzJtKXw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (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 did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4MKHJ40wVrz10RF; Sat, 3 Sep 2022 01:29:24 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 2831TOd5002643; Sat, 3 Sep 2022 01:29:24 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 2831TOWt002642; Sat, 3 Sep 2022 01:29:24 GMT (envelope-from git) Date: Sat, 3 Sep 2022 01:29:24 GMT Message-Id: <202209030129.2831TOWt002642@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Konstantin Belousov Subject: git: b8534da5ee54 - stable/13 - REAP_KILL_PROC: kill processes in the threaded taskqueue context 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: Sender: owner-dev-commits-src-branches@freebsd.org X-BeenThere: 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/13 X-Git-Reftype: branch X-Git-Commit: b8534da5ee54c75259dbbf8b5e54b0f261940714 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1662168564; 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=QRwSYD7/gEEpyCwlz/xyQ6nrTBvmPByj8g9tEgchNwo=; b=yJLvlTDtVI4cGX/KO8ouSg9ff0PvwY53l6SkYg/EW7ZybTLWCwVY2QqhoRUfo19y24IN+t Cq96j+r7Oy2zDHMSVX5xh6FWKIIGsEfZdaAgj5zSzLCkzy5KRAvfaCpuKYGmwN4y/J1rNr dUqVpFaTunpiPznjkXZ1Hu7PA7N0cb4tOnDkGnqPQWYXx2UoJrSrKZbAC2VdM0xNGxBpBm 3Uccemc9IZIggfQ+rPoqQXoHHE9vYw+tpVLzgks80T8ae8VgordlU/aNucj/8ENO+YIP6f Nkhwdj8tLXyp3lYZF2gZnbUf4jPGxhvWNwzK1aKZzsPzP99NwOyW7gT+PuIUKQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1662168564; a=rsa-sha256; cv=none; b=jhZAAX9oDbdEbHYP/Yh0wpqyT88SJwImHfMFvudbRVcpQ6WWUHqf+Pji+Q2PIa6+c1bcmR /uKG27WkxRdOqMoWX2BVyRszNtlQZXT4/+E2mg7BBisV+ncI129p47vIDlovjVc0f5v5DZ z9p99QWyXf8zZDZLYQ4Gj5pHoXw5VvSXvTezQRsCSK/LU6YQwI4zM9DyM9qRqI6UqN9CR/ mdAlxhRgXI/fCTenK8q/zF5Be7sQRFhbGS7F3YZ2pAmIuScrpRc3U0MHmZOOM++A30LFuf qTphYJmkfUst6h4ckDiUiWO67f9qNP0XZ+nduHxA4wkIMw05NzVXtB5o0udaOw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch stable/13 has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=b8534da5ee54c75259dbbf8b5e54b0f261940714 commit b8534da5ee54c75259dbbf8b5e54b0f261940714 Author: Konstantin Belousov AuthorDate: 2022-08-12 19:37:08 +0000 Commit: Konstantin Belousov CommitDate: 2022-09-03 01:17:36 +0000 REAP_KILL_PROC: kill processes in the threaded taskqueue context (cherry picked from commit 2842ec6d99ce3590eabb34d23eff5b0fed24eb98) --- sys/kern/kern_procctl.c | 183 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 124 insertions(+), 59 deletions(-) diff --git a/sys/kern/kern_procctl.c b/sys/kern/kern_procctl.c index 36372fd31bd4..1fb1183741d6 100644 --- a/sys/kern/kern_procctl.c +++ b/sys/kern/kern_procctl.c @@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -243,32 +244,29 @@ reap_getpids(struct thread *td, struct proc *p, void *data) return (error); } -static void -reap_kill_proc_relock(struct proc *p, int xlocked) -{ - PROC_UNLOCK(p); - if (xlocked) - sx_xlock(&proctree_lock); - else - sx_slock(&proctree_lock); - PROC_LOCK(p); -} +struct reap_kill_proc_work { + struct ucred *cr; + struct proc *target; + ksiginfo_t *ksi; + struct procctl_reaper_kill *rk; + int *error; + struct task t; +}; static void -reap_kill_proc_locked(struct thread *td, struct proc *p2, - ksiginfo_t *ksi, struct procctl_reaper_kill *rk, int *error) +reap_kill_proc_locked(struct reap_kill_proc_work *w) { - int error1, r, xlocked; + int error1; bool need_stop; - PROC_LOCK_ASSERT(p2, MA_OWNED); - PROC_ASSERT_HELD(p2); + PROC_LOCK_ASSERT(w->target, MA_OWNED); + PROC_ASSERT_HELD(w->target); - error1 = p_cansignal(td, p2, rk->rk_sig); + error1 = cr_cansignal(w->cr, w->target, w->rk->rk_sig); if (error1 != 0) { - if (*error == ESRCH) { - rk->rk_fpid = p2->p_pid; - *error = error1; + if (*w->error == ESRCH) { + w->rk->rk_fpid = w->target->p_pid; + *w->error = error1; } return; } @@ -286,39 +284,34 @@ reap_kill_proc_locked(struct thread *td, struct proc *p2, * thread signals the whole subtree, it is an application * race. */ - need_stop = p2 != td->td_proc && - (td->td_proc->p_flag2 & P2_WEXIT) == 0 && - (p2->p_flag & (P_KPROC | P_SYSTEM | P_STOPPED)) == 0 && - (rk->rk_flags & REAPER_KILL_CHILDREN) == 0; - - if (need_stop) { - xlocked = sx_xlocked(&proctree_lock); - sx_unlock(&proctree_lock); - r = thread_single(p2, SINGLE_ALLPROC); - reap_kill_proc_relock(p2, xlocked); - if (r != 0) - need_stop = false; - } + 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; - pksignal(p2, rk->rk_sig, ksi); - rk->rk_killed++; - *error = error1; + (void)pksignal(w->target, w->rk->rk_sig, w->ksi); + w->rk->rk_killed++; + *w->error = error1; if (need_stop) - thread_single_end(p2, SINGLE_ALLPROC); + thread_single_end(w->target, SINGLE_ALLPROC); } static void -reap_kill_proc(struct thread *td, struct proc *p2, ksiginfo_t *ksi, - struct procctl_reaper_kill *rk, int *error) +reap_kill_proc_work(void *arg, int pending __unused) { - PROC_LOCK(p2); - if ((p2->p_flag2 & P2_WEXIT) == 0) { - _PHOLD_LITE(p2); - reap_kill_proc_locked(td, p2, ksi, rk, error); - _PRELE(p2); - } - PROC_UNLOCK(p2); + 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 reap_kill_tracker { @@ -357,25 +350,40 @@ reap_kill_children(struct thread *td, struct proc *reaper, struct procctl_reaper_kill *rk, ksiginfo_t *ksi, int *error) { struct proc *p2; + int error1; LIST_FOREACH(p2, &reaper->p_children, p_sibling) { - (void)reap_kill_proc(td, p2, ksi, rk, error); - /* - * Do not end the loop on error, signal everything we - * can. - */ + PROC_LOCK(p2); + if ((p2->p_flag2 & P2_WEXIT) == 0) { + error1 = p_cansignal(td, p2, rk->rk_sig); + if (error1 != 0) { + if (*error == ESRCH) { + rk->rk_fpid = p2->p_pid; + *error = error1; + } + + /* + * Do not end the loop on error, + * signal everything we can. + */ + } else { + (void)pksignal(p2, rk->rk_sig, ksi); + rk->rk_killed++; + } + } + PROC_UNLOCK(p2); } } static bool reap_kill_subtree_once(struct thread *td, struct proc *p, struct proc *reaper, - struct procctl_reaper_kill *rk, ksiginfo_t *ksi, int *error, - struct unrhdr *pids) + struct unrhdr *pids, struct reap_kill_proc_work *w) { struct reap_kill_tracker_head tracker; struct reap_kill_tracker *t; struct proc *p2; - bool res; + int r, xlocked; + bool res, st; res = false; TAILQ_INIT(&tracker); @@ -397,14 +405,54 @@ reap_kill_subtree_once(struct thread *td, struct proc *p, struct proc *reaper, LIST_FOREACH(p2, &t->parent->p_reaplist, p_reapsibling) { if (t->parent == reaper && - (rk->rk_flags & REAPER_KILL_SUBTREE) != 0 && - p2->p_reapsubtree != rk->rk_subtree) + (w->rk->rk_flags & REAPER_KILL_SUBTREE) != 0 && + p2->p_reapsubtree != w->rk->rk_subtree) continue; if ((p2->p_treeflag & P_TREE_REAPER) != 0) reap_kill_sched(&tracker, p2); if (alloc_unr_specific(pids, p2->p_pid) != p2->p_pid) continue; - reap_kill_proc(td, p2, ksi, rk, error); + 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); + 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_LITE(p2); + 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); + } res = true; } reap_kill_sched_free(t); @@ -414,7 +462,7 @@ reap_kill_subtree_once(struct thread *td, struct proc *p, struct proc *reaper, static void reap_kill_subtree(struct thread *td, struct proc *p, struct proc *reaper, - struct procctl_reaper_kill *rk, ksiginfo_t *ksi, int *error) + struct reap_kill_proc_work *w) { struct unrhdr pids; @@ -431,7 +479,7 @@ reap_kill_subtree(struct thread *td, struct proc *p, struct proc *reaper, } td->td_proc->p_singlethr++; PROC_UNLOCK(td->td_proc); - while (reap_kill_subtree_once(td, p, reaper, rk, ksi, error, &pids)) + while (reap_kill_subtree_once(td, p, reaper, &pids, w)) ; PROC_LOCK(td->td_proc); td->td_proc->p_singlethr--; @@ -455,6 +503,7 @@ reap_kill_sapblk(struct thread *td __unused, void *data) static int reap_kill(struct thread *td, struct proc *p, void *data) { + struct reap_kill_proc_work w; struct proc *reaper; ksiginfo_t ksi; struct procctl_reaper_kill *rk; @@ -483,7 +532,23 @@ reap_kill(struct thread *td, struct proc *p, void *data) if ((rk->rk_flags & REAPER_KILL_CHILDREN) != 0) { reap_kill_children(td, reaper, rk, &ksi, &error); } else { - reap_kill_subtree(td, p, reaper, rk, &ksi, &error); + w.cr = crhold(td->td_ucred); + w.ksi = &ksi; + w.rk = rk; + w.error = &error; + TASK_INIT(&w.t, 0, reap_kill_proc_work, &w); + + /* + * Prevent swapout, since w, ksi, and possibly rk, are + * allocated on the stack. We sleep in + * reap_kill_subtree_once() waiting for task to + * complete single-threading. + */ + PHOLD(td->td_proc); + + reap_kill_subtree(td, p, reaper, &w); + PRELE(td->td_proc); + crfree(w.cr); } PROC_LOCK(p); return (error);