From nobody Sat Aug 1 12:19:25 2026 X-Original-To: dev-commits-src-all@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 4hC2724hZhz6mtWV for ; Sat, 01 Aug 2026 12:19:26 +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 "YR1" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4hC2721G2dz4B3p for ; Sat, 01 Aug 2026 12:19:26 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1785586766; 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=r5G4HCG16ELigkn5HW95WBQWMoVnVZqY2E8vlwiQUvc=; b=XZMX3InHNOFORkFwKrkfl/szlxt9LbX4df4fV4QyG2avAWZnsKN/KAr29ANmDNwaODirJK sRF2gC38GgTBhLkAF5qgszR2U6Etzw7N30tNReFHv63S5wEec2YOYVt1IBFmb3A2NBDl5Y 7BQY+06LcE4sZvC08ylxygEt1ekyXNEWH3NyGWV9+d9eeH9kmHJk0JaYWD8wdHevrhJ/HB vo9nq8YaPoAis3s0YEXl6l/9SehQZ9tHwnFeWa23+BWFsiBGONJL92vH4bt8B4uPHc5Qu0 SSDJFoKnQ4aL9sPYF5Aeg0OW8VJOH9m1dgRR3FkU0aeS0s2t3RGRRze0l6mM6w== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1785586766; a=rsa-sha256; cv=none; b=m9t5mCjBEUBx1PPeQDt80QU2r/JEKts2EsTLtk2C9ZDTBD0O8y3yxmBw+TfAi2ad4RQOEf beret4Bqj1s8oYGBkel8E+xub2nnh/IO79A/u5R9RZrQBT32gseEn9/XUBxvcz4+0z8vCM uqLElPi59VPGAyWfhT5okdwqEY9FZepz87XBz9Piqn2P5e2yNES15aF8v8Nxv6V3NUiJWY B1fTk18LKISStosFAztX8VZR0kVv6IAzvYVmjB6uU6RcnYp58s9vgNZx2lxjJJKpgJ2qVc XnkG08hYiGLSAbkFCjHv7KuV0KAodRt9XvXMg89Ekus1YZaWQOtka3ZCNz3hnA== 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=1785586766; 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=r5G4HCG16ELigkn5HW95WBQWMoVnVZqY2E8vlwiQUvc=; b=Q+yQvOXXqt4f74Ij2MVLW0fiXJ8vtoAelVvIG4JCn8fsoemgs4y4EC1r7clrTVgsBgY017 LIKvkovXUEnxsQSx+jiweXL+egYyHoMZU+gmwp9dKu9OEQH0bs2l+O+1qeN+lmL45k0zMg zfydTlfI+01XykLqdTGxfHTVWRoSm9m+sPke3ozc1QKEFL4XAcFcHwqO+e+bkYDSQ3gLJi HCC1PPNkXGDlUbDk+Z1Wv5dPW+/hYUd5ZZMGDMRBeHQvNtxhtd2IFayfgEBhnBPa9dsYN1 hxIGRNiPDCRrx1BWa+s8RonxbiZoAhiwpGW/M5JigkIjSvSiW4n7ylN8Fmso/g== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hC27171x8zksJ for ; Sat, 01 Aug 2026 12:19:25 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 1d6b4 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sat, 01 Aug 2026 12:19:25 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Konstantin Belousov Subject: git: 7da4edd30098 - main - pdwait(2): change handling of the exited processes List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list 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/main X-Git-Reftype: branch X-Git-Commit: 7da4edd300984abe67ff503828c1674a28e4b8b0 Auto-Submitted: auto-generated Date: Sat, 01 Aug 2026 12:19:25 +0000 Message-Id: <6a6de44d.1d6b4.7899d7a8@gitrepo.freebsd.org> The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=7da4edd300984abe67ff503828c1674a28e4b8b0 commit 7da4edd300984abe67ff503828c1674a28e4b8b0 Author: Konstantin Belousov AuthorDate: 2026-07-28 00:31:51 +0000 Commit: Konstantin Belousov CommitDate: 2026-08-01 10:41:35 +0000 pdwait(2): change handling of the exited processes Instead of accessing the struct proc and gathering data from it, memoize the data needed for pdwait() on exited process in struct procdesc, at the time of process termination. This allows unlimited number of calls to pdwait(2) on procdesc for terminated process. Change the locking requirements for pd_flags to proctree_lock. This does not modify the pre-patch locking regime, but the change requires it. Reviewed by: markj Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D58407 --- sys/kern/kern_exit.c | 27 ++++++++++++++++++--------- sys/kern/sys_procdesc.c | 29 +++++++++++++++++++++++++---- sys/sys/procdesc.h | 11 +++++++++-- 3 files changed, 52 insertions(+), 15 deletions(-) diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index 2e8e95e33d8c..b61fb7bcf2f1 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -1578,29 +1578,38 @@ kern_pdwait(struct thread *td, int fd, int *status, ("closed proc %p procdesc %p pd flags %#x", pd->pd_proc, pd, pd->pd_flags)); + if ((pd->pd_flags & PDF_EXITED) != 0) { + if ((options & WEXITED) == 0) { + error = ESRCH; + goto exit_tree_locked; + } + procdesc_fill_winfo(pd, false); + *status = KW_EXITCODE(pd->pd_xexit, pd->pd_xsig); + if (wrusage != NULL) { + memcpy(wrusage, &pd->pd_wrusage, + sizeof(*wrusage)); + } + if (siginfo != NULL) { + memcpy(siginfo, &pd->pd_siginfo, + sizeof(*siginfo)); + } + goto exit_tree_locked; + } p = pd->pd_proc; if (p == NULL) { error = ESRCH; goto exit_tree_locked; } PROC_LOCK(p); + MPASS(p->p_state != PRS_ZOMBIE); error = p_canwait(td, p); if (error != 0) break; - if ((options & WEXITED) == 0 && p->p_state == PRS_ZOMBIE) { - error = ESRCH; - break; - } wait_fill_siginfo(p, siginfo); wait_fill_wrusage(p, wrusage); - if (p->p_state == PRS_ZOMBIE) { - proc_reap(td, p, status, options); - goto exit_unlocked; - } - if (wait6_check_alive(td, options, p, status, siginfo)) goto exit_unlocked; diff --git a/sys/kern/sys_procdesc.c b/sys/kern/sys_procdesc.c index 608771b9f38c..a605633fbca5 100644 --- a/sys/kern/sys_procdesc.c +++ b/sys/kern/sys_procdesc.c @@ -295,7 +295,8 @@ procdesc_exit(struct proc *p) KASSERT(pd->pd_fpcount > 0, ("%s: closed procdesc %p", __func__, pd)); pd->pd_flags |= PDF_EXITED; - pd->pd_xstat = KW_EXITCODE(p->p_xexit, p->p_xsig); + pd->pd_xexit = p->p_xexit; + pd->pd_xsig = p->p_xsig; selwakeup(&pd->pd_selinfo); KNOTE_LOCKED(&pd->pd_selinfo.si_note, NOTE_EXIT | NOTE_PDSIGCHLD); @@ -337,6 +338,25 @@ procdesc_fork(struct proc *p, pid_t child_pid) PROC_UNLOCK(p); } +void +procdesc_fill_winfo(struct procdesc *pd, bool proc_locked) +{ + struct proc *p; + + sx_assert(&proctree_lock, SA_XLOCKED); + + if ((pd->pd_flags & (PDF_EXITED | PDF_EXIT_INFO)) == PDF_EXITED) { + pd->pd_flags |= PDF_EXIT_INFO; + p = pd->pd_proc; + if (!proc_locked) + PROC_LOCK(p); + wait_fill_siginfo(p, &pd->pd_siginfo); + wait_fill_wrusage(p, &pd->pd_wrusage); + if (!proc_locked) + PROC_UNLOCK(p); + } +} + /* * When a process descriptor is reaped, perhaps as a result of close(), release * the process's reference on the process descriptor. @@ -350,6 +370,7 @@ procdesc_reap(struct proc *p) KASSERT(p->p_procdesc != NULL, ("procdesc_reap: p_procdesc == NULL")); pd = p->p_procdesc; + procdesc_fill_winfo(pd, false); pd->pd_proc = NULL; p->p_procdesc = NULL; procdesc_free(pd); @@ -458,7 +479,7 @@ procdesc_poll(struct file *fp, int events, struct ucred *active_cred, revents = 0; pd = fp->f_data; PROCDESC_LOCK(pd); - if (pd->pd_flags & PDF_EXITED) + if ((atomic_load_int(&pd->pd_flags) & PDF_EXITED) != 0) revents |= POLLHUP; else selrecord(td, &pd->pd_selinfo); @@ -491,7 +512,7 @@ procdesc_kqops_event(struct knote *kn, long hint) * pending. */ p = pd->pd_proc; - if ((pd->pd_flags & PDF_EXITED) != 0) + if ((atomic_load_int(&pd->pd_flags) & PDF_EXITED) != 0) event = NOTE_EXIT | NOTE_PDSIGCHLD; else if ((atomic_load_int(&p->p_flag) & (P_STOPPED_SIG | P_STOPPED_TRACE)) != 0) @@ -509,7 +530,7 @@ procdesc_kqops_event(struct knote *kn, long hint) /* Report exit status */ if ((kn->kn_fflags & NOTE_EXIT) != 0) - kn->kn_data = pd->pd_xstat; + kn->kn_data = KW_EXITCODE(pd->pd_xexit, pd->pd_xsig); /* Process is gone, so flag the event as finished. */ if ((event & NOTE_REAP) != 0 || diff --git a/sys/sys/procdesc.h b/sys/sys/procdesc.h index bb486d9026ba..f912f8787fd9 100644 --- a/sys/sys/procdesc.h +++ b/sys/sys/procdesc.h @@ -71,10 +71,15 @@ struct procdesc { /* * In-flight data and notification of events. */ - int pd_flags; /* (p) PD_ flags. */ - u_short pd_xstat; /* (p) Exit status. */ + int pd_flags; /* (t) PD_ flags. */ struct selinfo pd_selinfo; /* (p) Event notification. */ struct mtx pd_lock; /* Protect data + events. */ + + /* Exit status. */ + u_int pd_xexit; + u_int pd_xsig; + struct __wrusage pd_wrusage; + siginfo_t pd_siginfo; }; /* @@ -89,6 +94,7 @@ struct procdesc { /* * Flags for the pd_flags field. */ +#define PDF_EXIT_INFO 0x00000001 /* Exit info calculated. */ #define PDF_EXITED 0x00000004 /* Process exited. */ /* @@ -111,6 +117,7 @@ void procdesc_new(struct proc *, int); void procdesc_finit(struct procdesc *, struct file *); pid_t procdesc_pid(struct file *); void procdesc_reap(struct proc *); +void procdesc_fill_winfo(struct procdesc *pd, bool proc_locked); int procdesc_falloc(struct thread *, struct file **, int *, int, struct filecaps *);