git: cd349e1bcd21 - stable/15 - procdesc: track count of open files
Konstantin Belousov <[email protected]>
| Newsgroups | gmane.os.freebsd.devel.cvs.src |
|---|---|
| Message-ID | <6a81248a.447af.47045d46__22292.9198456526$1786848523$gmane$org@gitrepo.freebsd.org> |
The branch stable/15 has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=cd349e1bcd21bbf9fd8834550cb6b8305977472c commit cd349e1bcd21bbf9fd8834550cb6b8305977472c Author: Konstantin Belousov <[email protected]> AuthorDate: 2026-05-21 00:47:20 +0000 Commit: Konstantin Belousov <[email protected]> CommitDate: 2026-08-16 02:41:21 +0000 procdesc: track count of open files (cherry picked from commit 18b6bb5231bf1c927a6f8de24e466764fe1f7470) --- sys/kern/kern_exit.c | 4 ++-- sys/kern/sys_procdesc.c | 17 +++++++++++------ sys/sys/procdesc.h | 4 +++- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index b20009f46139..73c5a6f9f224 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -1577,8 +1577,8 @@ kern_pdwait(struct thread *td, int fd, int *status, for (;;) { /* We own a reference on the procdesc file. */ - KASSERT((pd->pd_flags & PDF_CLOSED) == 0, - ("PDF_CLOSED proc %p procdesc %p pd flags %#x", + KASSERT(pd->pd_fpcount > 0, + ("closed proc %p procdesc %p pd flags %#x", p, pd, pd->pd_flags)); sx_xlock(&proctree_lock); diff --git a/sys/kern/sys_procdesc.c b/sys/kern/sys_procdesc.c index 3c99f0241016..a3e234be7e39 100644 --- a/sys/kern/sys_procdesc.c +++ b/sys/kern/sys_procdesc.c @@ -219,6 +219,7 @@ procdesc_alloc(int flags) * struct file, and the other from their struct proc. */ refcount_init(&pd->pd_refcount, 2); + pd->pd_fpcount = 1; return (pd); } @@ -293,8 +294,8 @@ procdesc_free(struct procdesc *pd) if (refcount_release(&pd->pd_refcount)) { KASSERT(pd->pd_proc == NULL, ("procdesc_free: pd_proc != NULL")); - KASSERT((pd->pd_flags & PDF_CLOSED), - ("procdesc_free: !PDF_CLOSED")); + KASSERT(pd->pd_fpcount == 0, + ("procdesc_free: not closed %p %d", pd, pd->pd_fpcount)); if (pd->pd_pid != -1) proc_id_clear(PROC_ID_PID, pd->pd_pid); @@ -322,7 +323,7 @@ procdesc_exit(struct proc *p) pd = p->p_procdesc; PROCDESC_LOCK(pd); - KASSERT((pd->pd_flags & PDF_CLOSED) == 0 || p->p_pptr == p->p_reaper, + KASSERT(pd->pd_fpcount > 0 || p->p_pptr == p->p_reaper, ("procdesc_exit: closed && parent not reaper")); pd->pd_flags |= PDF_EXITED; @@ -334,7 +335,7 @@ procdesc_exit(struct proc *p) * Clean up the procdesc now rather than letting it happen during * that reap. */ - if (pd->pd_flags & PDF_CLOSED) { + if (pd->pd_fpcount == 0) { PROCDESC_UNLOCK(pd); pd->pd_proc = NULL; p->p_procdesc = NULL; @@ -388,7 +389,8 @@ procdesc_close(struct file *fp, struct thread *td) sx_xlock(&proctree_lock); PROCDESC_LOCK(pd); - pd->pd_flags |= PDF_CLOSED; + MPASS(pd->pd_fpcount > 0); + pd->pd_fpcount--; PROCDESC_UNLOCK(pd); p = pd->pd_proc; if (p == NULL) { @@ -408,7 +410,7 @@ procdesc_close(struct file *fp, struct thread *td) * calls back into procdesc_reap(). */ proc_reap(curthread, p, NULL, 0); - } else { + } else if (pd->pd_fpcount == 0) /* last procdesc */ { /* * If the process is not yet dead, we need to kill it, * but we can't wait around synchronously for it to go @@ -438,6 +440,9 @@ procdesc_close(struct file *fp, struct thread *td) kern_psignal(p, SIGKILL); PROC_UNLOCK(p); sx_xunlock(&proctree_lock); + } else { + PROC_UNLOCK(p); + sx_xunlock(&proctree_lock); } } diff --git a/sys/sys/procdesc.h b/sys/sys/procdesc.h index a6be5dbe576c..08b563828b95 100644 --- a/sys/sys/procdesc.h +++ b/sys/sys/procdesc.h @@ -51,6 +51,8 @@ * (r) - Atomic reference count. * (s) - Protected by selinfo. * (t) - Protected by the proctree_lock + * (p|t) - Both procree_lock and process descriptor must be locked + * for pd_fpcount */ struct proc; struct sigio; @@ -63,6 +65,7 @@ struct procdesc { struct proc *pd_proc; /* (t) Process. */ pid_t pd_pid; /* (c) Cached pid. */ u_int pd_refcount; /* (r) Reference count. */ + u_int pd_fpcount; /* (p|t) files referencing me */ /* * In-flight data and notification of events. @@ -85,7 +88,6 @@ struct procdesc { /* * Flags for the pd_flags field. */ -#define PDF_CLOSED 0x00000001 /* Descriptor has closed. */ #define PDF_EXITED 0x00000004 /* Process exited. */ #define PDF_DAEMON 0x00000008 /* Don't exit when procdesc closes. */