The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=2b67cfa39d8367a021d165681a1e7f54c6020470
commit 2b67cfa39d8367a021d165681a1e7f54c6020470 Author: Konstantin Belousov <[email protected]> AuthorDate: 2026-01-08 04:19:04 +0000 Commit: Konstantin Belousov <[email protected]> CommitDate: 2026-01-25 15:53:30 +0000 kern/kern_exit.c: extract some helpers from proc_to_reap() Reviewed by: asomers, markj Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D54592 --- sys/kern/kern_exit.c | 116 +++++++++++++++++++++++++++++---------------------- 1 file changed, 66 insertions(+), 50 deletions(-) diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index db6e91f00534..2b22e3a0a23b 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -1042,13 +1042,75 @@ proc_reap(struct thread *td, struct proc *p, int *status, int options) atomic_add_int(&nprocs, -1); } +static void +wait_fill_siginfo(struct proc *p, siginfo_t *siginfo) +{ + PROC_LOCK_ASSERT(p, MA_OWNED); + + if (siginfo == NULL) + return; + + bzero(siginfo, sizeof(*siginfo)); + siginfo->si_errno = 0; + + /* + * SUSv4 requires that the si_signo value is always + * SIGCHLD. Obey it despite the rfork(2) interface allows to + * request other signal for child exit notification. + */ + siginfo->si_signo = SIGCHLD; + + /* + * This is still a rough estimate. We will fix the cases + * TRAPPED, STOPPED, and CONTINUED later. + */ + if (WCOREDUMP(p->p_xsig)) { + siginfo->si_code = CLD_DUMPED; + siginfo->si_status = WTERMSIG(p->p_xsig); + } else if (WIFSIGNALED(p->p_xsig)) { + siginfo->si_code = CLD_KILLED; + siginfo->si_status = WTERMSIG(p->p_xsig); + } else { + siginfo->si_code = CLD_EXITED; + siginfo->si_status = p->p_xexit; + } + + siginfo->si_pid = p->p_pid; + siginfo->si_uid = p->p_ucred->cr_uid; + + /* + * The si_addr field would be useful additional detail, but + * apparently the PC value may be lost when we reach this + * point. bzero() above sets siginfo->si_addr to NULL. + */ +} + +static void +wait_fill_wrusage(struct proc *p, struct __wrusage *wrusage) +{ + struct rusage *rup; + + PROC_LOCK_ASSERT(p, MA_OWNED); + + if (wrusage == NULL) + return; + + rup = &wrusage->wru_self; + *rup = p->p_ru; + PROC_STATLOCK(p); + calcru(p, &rup->ru_utime, &rup->ru_stime); + PROC_STATUNLOCK(p); + + rup = &wrusage->wru_children; + *rup = p->p_stats->p_cru; + calccru(p, &rup->ru_utime, &rup->ru_stime); +} + static int proc_to_reap(struct thread *td, struct proc *p, idtype_t idtype, id_t id, int *status, int options, struct __wrusage *wrusage, siginfo_t *siginfo, int check_only) { - struct rusage *rup; - sx_assert(&proctree_lock, SA_XLOCKED); PROC_LOCK(p); @@ -1133,60 +1195,14 @@ proc_to_reap(struct thread *td, struct proc *p, idtype_t idtype, id_t id, return (0); } - if (siginfo != NULL) { - bzero(siginfo, sizeof(*siginfo)); - siginfo->si_errno = 0; - - /* - * SUSv4 requires that the si_signo value is always - * SIGCHLD. Obey it despite the rfork(2) interface - * allows to request other signal for child exit - * notification. - */ - siginfo->si_signo = SIGCHLD; - - /* - * This is still a rough estimate. We will fix the - * cases TRAPPED, STOPPED, and CONTINUED later. - */ - if (WCOREDUMP(p->p_xsig)) { - siginfo->si_code = CLD_DUMPED; - siginfo->si_status = WTERMSIG(p->p_xsig); - } else if (WIFSIGNALED(p->p_xsig)) { - siginfo->si_code = CLD_KILLED; - siginfo->si_status = WTERMSIG(p->p_xsig); - } else { - siginfo->si_code = CLD_EXITED; - siginfo->si_status = p->p_xexit; - } - - siginfo->si_pid = p->p_pid; - siginfo->si_uid = p->p_ucred->cr_uid; - - /* - * The si_addr field would be useful additional - * detail, but apparently the PC value may be lost - * when we reach this point. bzero() above sets - * siginfo->si_addr to NULL. - */ - } + wait_fill_siginfo(p, siginfo); /* * There should be no reason to limit resources usage info to * exited processes only. A snapshot about any resources used * by a stopped process may be exactly what is needed. */ - if (wrusage != NULL) { - rup = &wrusage->wru_self; - *rup = p->p_ru; - PROC_STATLOCK(p); - calcru(p, &rup->ru_utime, &rup->ru_stime); - PROC_STATUNLOCK(p); - - rup = &wrusage->wru_children; - *rup = p->p_stats->p_cru; - calccru(p, &rup->ru_utime, &rup->ru_stime); - } + wait_fill_wrusage(p, wrusage); if (p->p_state == PRS_ZOMBIE && !check_only) { proc_reap(td, p, status, options);
