Index | Thread | Search

From:
Vitaliy Makkoveev <mvs@openbsd.org>
Subject:
mp-safe random*_filtops
To:
Visa Hankala <visa@openbsd.org>, tech@openbsd.org
Date:
Mon, 21 Jul 2025 13:36:42 +0300

Download raw body.

Thread
  • Vitaliy Makkoveev:

    mp-safe random*_filtops

This is a kind of `seltrue_filtops', so we only need to implement
f_modify and f_process handlers. No locks required.

This time the `seltrue_filtops' handlers are local to kern/kern_event.c,
but if we want, the .f_detach, .f_modify and .f_process handlers could
be used as-is for `random*_filtops'.

Index: sys/dev/rnd.c
===================================================================
RCS file: /cvs/src/sys/dev/rnd.c,v
diff -u -p -r1.230 rnd.c
--- sys/dev/rnd.c	30 Dec 2024 02:46:00 -0000	1.230
+++ sys/dev/rnd.c	21 Jul 2025 10:25:04 -0000
@@ -150,24 +150,30 @@ void	extract_entropy(u_int8_t *)
 struct timeout rnd_timeout = TIMEOUT_INITIALIZER(dequeue_randomness, NULL);
 
 int	filt_randomread(struct knote *, long);
-void	filt_randomdetach(struct knote *);
 int	filt_randomwrite(struct knote *, long);
+void	filt_randomdetach(struct knote *);
+int	filt_randommodify(struct kevent *, struct knote *);
+int	filt_randomprocess(struct knote *, struct kevent *);
 
 static void _rs_seed(u_char *, size_t);
 static void _rs_clearseed(const void *p, size_t s);
 
 const struct filterops randomread_filtops = {
-	.f_flags	= FILTEROP_ISFD,
+	.f_flags	= FILTEROP_ISFD | FILTEROP_MPSAFE,
 	.f_attach	= NULL,
 	.f_detach	= filt_randomdetach,
 	.f_event	= filt_randomread,
+	.f_modify	= filt_randommodify,
+	.f_process	= filt_randomprocess,
 };
 
 const struct filterops randomwrite_filtops = {
-	.f_flags	= FILTEROP_ISFD,
+	.f_flags	= FILTEROP_ISFD | FILTEROP_MPSAFE,
 	.f_attach	= NULL,
 	.f_detach	= filt_randomdetach,
 	.f_event	= filt_randomwrite,
+	.f_modify	= filt_randommodify,
+	.f_process	= filt_randomprocess,
 };
 
 /*
@@ -776,6 +782,23 @@ randomkqfilter(dev_t dev, struct knote *
 void
 filt_randomdetach(struct knote *kn)
 {
+}
+
+int
+filt_randommodify(struct kevent *kev, struct knote *kn)
+{
+	knote_assign(kev, kn);
+	return (kn->kn_fop->f_event(kn, 0));
+}
+
+int
+filt_randomprocess(struct knote *kn, struct kevent *kev)
+{
+	int active;
+
+	if ((active = kn->kn_fop->f_event(kn, 0)))
+		knote_submit(kn, kev);
+	return (active);
 }
 
 int