git: 2bacbbecb165 - main - kqueue: Add NOTE_REAP

Dag-Erling Smørgrav <[email protected]>
Newsgroups gmane.os.freebsd.devel.cvs.src
Message-ID <6a67302c.1d4fb.541934be__44315.9486328781$1785147490$gmane$org@gitrepo.freebsd.org>
The branch main has been updated by des:

URL: https://cgit.FreeBSD.org/src/commit/?id=2bacbbecb165dd761ea7ec2fc35630db61508cdf

commit 2bacbbecb165dd761ea7ec2fc35630db61508cdf
Author:     Dag-Erling Smørgrav <[email protected]>
AuthorDate: 2026-07-27 10:15:26 +0000
Commit:     Dag-Erling Smørgrav <[email protected]>
CommitDate: 2026-07-27 10:15:26 +0000

    kqueue: Add NOTE_REAP
    
    Add a NOTE_REAP event for EVFILTER_PROC which provides a notification
    when the process is reaped.
    
    MFC after:      1 week
    Sponsored by:   Klara, Inc.
    Sponsored by:   NetApp, Inc.
    Reviewed by:    kib, markj
    Differential Revision:  https://reviews.freebsd.org/D58313
---
 lib/libsys/kqueue.2      | 10 ++++++++--
 lib/libsysdecode/flags.c |  2 +-
 sys/kern/kern_event.c    | 13 ++++++++-----
 sys/kern/kern_exit.c     |  1 +
 sys/kern/sys_procdesc.c  |  9 ++++++---
 sys/sys/event.h          | 11 ++++-------
 6 files changed, 28 insertions(+), 18 deletions(-)

diff --git a/lib/libsys/kqueue.2 b/lib/libsys/kqueue.2
index d2c6ed102f29..6d2a10b1b139 100644
--- a/lib/libsys/kqueue.2
+++ b/lib/libsys/kqueue.2
@@ -22,7 +22,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd January 24, 2026
+.Dd July 22, 2026
 .Dt KQUEUE 2
 .Os
 .Sh NAME
@@ -543,9 +543,15 @@ The exit status will be stored in
 .Va data
 in the same format as the status returned by
 .Xr wait 2 .
+.It Dv NOTE_REAP
+The process has been reaped by a call to the
+.Xr wait 2
+family of functions.
 .It Dv NOTE_FORK
 The process has called
-.Fn fork .
+.Xr fork 2
+or
+.Xr vfork 2 .
 .It Dv NOTE_EXEC
 The process has executed a new process via
 .Xr execve 2
diff --git a/lib/libsysdecode/flags.c b/lib/libsysdecode/flags.c
index 880fe5e1ed49..b9af84a1ef52 100644
--- a/lib/libsysdecode/flags.c
+++ b/lib/libsysdecode/flags.c
@@ -377,7 +377,7 @@ static struct name_table kevent_vnode_fflags[] = {
 };
 
 static struct name_table kevent_proc_fflags[] = {
-	X(NOTE_EXIT) X(NOTE_FORK) X(NOTE_EXEC) X(NOTE_PDSIGCHLD)
+	X(NOTE_EXIT) X(NOTE_FORK) X(NOTE_EXEC) X(NOTE_PDSIGCHLD) X(NOTE_REAP)
 	X(NOTE_TRACK) X(NOTE_TRACKERR) X(NOTE_CHILD) XEND
 };
 
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index f22d8ca7da11..23e9d309f74c 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -445,7 +445,7 @@ filt_procattach(struct knote *kn)
 	bool exiting, immediate;
 
 	exiting = immediate = false;
-	if (kn->kn_sfflags & NOTE_EXIT)
+	if (kn->kn_sfflags & (NOTE_EXIT | NOTE_REAP))
 		p = pfind_any(kn->kn_id);
 	else
 		p = pfind(kn->kn_id);
@@ -470,7 +470,7 @@ filt_procattach(struct knote *kn)
 		kn->kn_flags &= ~EV_FLAG2;
 		kn->kn_data = kn->kn_sdata;		/* ppid */
 		kn->kn_fflags = NOTE_CHILD;
-		kn->kn_sfflags &= ~(NOTE_EXIT | NOTE_EXEC | NOTE_FORK);
+		kn->kn_sfflags &= ~NOTE_PCTRLMASK;
 		immediate = true; /* Force immediate activation of child note. */
 	}
 	/*
@@ -532,12 +532,15 @@ filt_proc(struct knote *kn, long hint)
 	if ((kn->kn_sfflags & event) != 0)
 		kn->kn_fflags |= kn->kn_sfflags & event;
 
+	/* Report exit status */
+	if ((kn->kn_fflags & NOTE_EXIT) != 0)
+		kn->kn_data = KW_EXITCODE(p->p_xexit, p->p_xsig);
+
 	/* Process is gone, so flag the event as finished. */
-	if ((event & NOTE_EXIT) != 0) {
+	if ((event & NOTE_REAP) != 0 ||
+	    ((event & NOTE_EXIT) != 0 && (kn->kn_sfflags & NOTE_REAP) == 0)) {
 		kn->kn_flags |= EV_EOF | EV_ONESHOT;
 		kn->kn_ptr.p_proc = NULL;
-		if (kn->kn_fflags & NOTE_EXIT)
-			kn->kn_data = KW_EXITCODE(p->p_xexit, p->p_xsig);
 		if (kn->kn_fflags == 0)
 			kn->kn_flags |= EV_DROP;
 		return (1);
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index 43d0c2da38c1..2aa756bd00d2 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -1055,6 +1055,7 @@ proc_reap(struct thread *td, struct proc *p, int *status, int options)
 	sx_xunlock(&proctree_lock);
 
 	PROC_LOCK(p);
+	KNOTE_LOCKED(p->p_klist, NOTE_REAP);
 	knlist_detach(p->p_klist);
 	p->p_klist = NULL;
 	PROC_UNLOCK(p);
diff --git a/sys/kern/sys_procdesc.c b/sys/kern/sys_procdesc.c
index 862b59262d0c..608771b9f38c 100644
--- a/sys/kern/sys_procdesc.c
+++ b/sys/kern/sys_procdesc.c
@@ -507,11 +507,14 @@ procdesc_kqops_event(struct knote *kn, long hint)
 	if ((kn->kn_sfflags & event) != 0)
 		kn->kn_fflags |= kn->kn_sfflags & event;
 
+	/* Report exit status */
+	if ((kn->kn_fflags & NOTE_EXIT) != 0)
+		kn->kn_data = pd->pd_xstat;
+
 	/* Process is gone, so flag the event as finished. */
-	if ((event & NOTE_EXIT) != 0) {
+	if ((event & NOTE_REAP) != 0 ||
+	    ((event & NOTE_EXIT) != 0 && (kn->kn_sfflags & NOTE_REAP) == 0)) {
 		kn->kn_flags |= EV_EOF | EV_ONESHOT;
-		if (kn->kn_fflags & NOTE_EXIT)
-			kn->kn_data = pd->pd_xstat;
 		if (kn->kn_fflags == 0)
 			kn->kn_flags |= EV_DROP;
 		return (1);
diff --git a/sys/sys/event.h b/sys/sys/event.h
index 9b8a3ba2bcf1..1944a7c2706a 100644
--- a/sys/sys/event.h
+++ b/sys/sys/event.h
@@ -209,7 +209,10 @@ struct freebsd11_kevent32 {
 #define	NOTE_EXEC	0x20000000		/* proc: process exec'd */
 #define	NOTE_PDSIGCHLD	0x10000000		/* procdesc: pdwait() info
 						   available */
-#define	NOTE_PCTRLMASK	0xf0000000		/* mask for hint bits */
+#define	NOTE_SIGNAL	0x08000000		/* process received a signal,
+						   shared with EVFIL_SIGNAL */
+#define	NOTE_REAP	0x04000000		/* process reaped */
+#define	NOTE_PCTRLMASK	0xfc000000		/* mask for hint bits */
 #define	NOTE_PDATAMASK	0x000fffff		/* mask for pid */
 
 /* additional flags for EVFILT_PROC */
@@ -263,12 +266,6 @@ struct knlist {
 
 #define	KNLIST_EMPTY(list)		SLIST_EMPTY(&(list)->kl_list)
 
-/*
- * Flag indicating hint is a signal.  Used by EVFILT_SIGNAL, and also
- * shared by EVFILT_PROC  (all knotes attached to p->p_klist)
- */
-#define NOTE_SIGNAL	0x08000000
-
 /*
  * Hint values for the optional f_touch event filter.  If f_touch is not set 
  * to NULL and f_isfd is zero the f_touch filter will be called with the type
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.