[libbsd 12/22] Move kqueue() and kevent(), avoid VFS

Sebastian Huber sebastian.huber at embedded-brains.de
Fri Jun 24 06:33:40 UTC 2022


Collecting all system calls in a single translation unit is not good due to the
library initialization through linker sets.

Revert commit 6514d561587fd1527fe6a26cb43e6b5742c8c779 in
"freebsd/sys/kern/kern_event.c".  The goal is to use USB, network, PCI, and
NVMe support without the VFS to reduce the memory and runtime overhead
introduced by VFS.

Update #4475.
---
 freebsd/sys/kern/kern_event.c          | 187 ++++++++++++++++++++++---
 freebsd/sys/sys/eventvar.h             |   2 +
 freebsd/sys/sys/sysproto.h             |   4 -
 rtemsbsd/rtems/rtems-bsd-syscall-api.c |  48 -------
 testsuite/syscalls01/test_main.c       |   7 +-
 5 files changed, 173 insertions(+), 75 deletions(-)

diff --git a/freebsd/sys/kern/kern_event.c b/freebsd/sys/kern/kern_event.c
index f5682b03..0d8332da 100644
--- a/freebsd/sys/kern/kern_event.c
+++ b/freebsd/sys/kern/kern_event.c
@@ -40,6 +40,9 @@ __FBSDID("$FreeBSD$");
 #define	_WANT_FREEBSD11_KEVENT
 #endif
 
+#ifdef __rtems__
+#include <rtems/bsd/sys/file.h>
+#endif /* __rtems__ */
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/capsicum.h>
@@ -81,6 +84,8 @@ __FBSDID("$FreeBSD$");
 
 #include <vm/uma.h>
 #ifdef __rtems__
+#include <machine/rtems-bsd-syscall-api.h>
+
 /* Maintain a global kqueue list on RTEMS */
 static struct kqlist fd_kqlist;
 #endif /* __rtems__ */
@@ -129,6 +134,7 @@ static int	kern_kevent_generic(struct thread *td,
 		    struct g_kevent_args *uap,
 		    struct kevent_copyops *k_ops, const char *struct_name);
 
+#ifndef __rtems__
 static fo_rdwr_t	kqueue_read;
 static fo_rdwr_t	kqueue_write;
 static fo_truncate_t	kqueue_truncate;
@@ -153,6 +159,9 @@ static struct fileops kqueueops = {
 	.fo_sendfile = invfo_sendfile,
 	.fo_fill_kinfo = kqueue_fill_kinfo,
 };
+#else /* __rtems__ */
+static const rtems_filesystem_file_handlers_r kqueueops;
+#endif /* __rtems__ */
 
 static int 	knote_attach(struct knote *kn, struct kqueue *kq);
 static void 	knote_drop(struct knote *kn, struct thread *td);
@@ -404,11 +413,7 @@ filt_fileattach(struct knote *kn)
 static int
 kqueue_kqfilter(struct file *fp, struct knote *kn)
 {
-#ifndef __rtems__
 	struct kqueue *kq = kn->kn_fp->f_data;
-#else /* __rtems__ */
-	struct kqueue *kq = rtems_bsd_knote_to_file(kn);
-#endif /* __rtems__ */
 
 	if (kn->kn_filter != EVFILT_READ)
 		return (EINVAL);
@@ -419,15 +424,20 @@ kqueue_kqfilter(struct file *fp, struct knote *kn)
 
 	return (0);
 }
+#ifdef __rtems__
+static int
+rtems_bsd_kqueue_kqfilter(rtems_libio_t *iop, struct knote *kn)
+{
+
+	(void)iop;
+	return kqueue_kqfilter(NULL, kn);
+}
+#endif /* __rtems__ */
 
 static void
 filt_kqdetach(struct knote *kn)
 {
-#ifndef __rtems__
 	struct kqueue *kq = kn->kn_fp->f_data;
-#else /* __rtems__ */
-	struct kqueue *kq = rtems_bsd_knote_to_file(kn);
-#endif /* __rtems__ */
 
 	knlist_remove(&kq->kq_sel.si_note, kn, 0);
 }
@@ -436,11 +446,7 @@ filt_kqdetach(struct knote *kn)
 static int
 filt_kqueue(struct knote *kn, long hint)
 {
-#ifndef __rtems__
 	struct kqueue *kq = kn->kn_fp->f_data;
-#else /* __rtems__ */
-	struct kqueue *kq = rtems_bsd_knote_to_file(kn);
-#endif /* __rtems__ */
 
 	kn->kn_data = kq->kq_count;
 	return (kn->kn_data > 0);
@@ -992,6 +998,12 @@ filt_usertouch(struct knote *kn, struct kevent *kev, u_long type)
 	}
 }
 
+#ifdef __rtems__
+static int
+kern_kqueue(struct thread *td, int flags, struct filecaps *fcaps);
+
+static
+#endif /* __rtems__ */
 int
 sys_kqueue(struct thread *td, struct kqueue_args *uap)
 {
@@ -1018,10 +1030,15 @@ kern_kqueue(struct thread *td, int flags, struct filecaps *fcaps)
 	struct ucred *cred;
 	int fd, error;
 
+#ifndef __rtems__
 	fdp = td->td_proc->p_fd;
 	cred = td->td_ucred;
 	if (!chgkqcnt(cred->cr_ruidinfo, 1, lim_cur(td, RLIMIT_KQUEUES)))
 		return (ENOMEM);
+#else /* __rtems__ */
+	(void)fdp;
+	(void)cred;
+#endif /* __rtems__ */
 
 	error = falloc_caps(td, &fp, &fd, flags, fcaps);
 	if (error != 0) {
@@ -1032,8 +1049,10 @@ kern_kqueue(struct thread *td, int flags, struct filecaps *fcaps)
 	/* An extra reference on `fp' has been held for us by falloc(). */
 	kq = malloc(sizeof *kq, M_KQUEUE, M_WAITOK | M_ZERO);
 	kqueue_init(kq);
+#ifndef __rtems__
 	kq->kq_fdp = fdp;
 	kq->kq_cred = crhold(cred);
+#endif /* __rtems__ */
 
 	FILEDESC_XLOCK(fdp);
 #ifndef __rtems__
@@ -1051,16 +1070,50 @@ kern_kqueue(struct thread *td, int flags, struct filecaps *fcaps)
 	td->td_retval[0] = fd;
 	return (0);
 }
+#ifdef __rtems__
+int
+kqueue(void)
+{
+	struct thread *td = rtems_bsd_get_curthread_or_null();
+	struct kqueue_args ua;
+	int error;
+
+	if (td != NULL) {
+		error = sys_kqueue(td, &ua);
+	} else {
+		error = ENOMEM;
+	}
+
+	if (error == 0) {
+		return td->td_retval[0];
+	} else {
+		rtems_set_errno_and_return_minus_one(error);
+	}
+}
+#endif /* __rtems__ */
 
 struct g_kevent_args {
 	int	fd;
+#ifndef __rtems__
 	void	*changelist;
+#else /* __rtems__ */
+	const void *changelist;
+#endif /* __rtems__ */
 	int	nchanges;
 	void	*eventlist;
 	int	nevents;
 	const struct timespec *timeout;
 };
 
+#ifdef __rtems__
+static int kern_kevent(struct thread *td, int fd, int nchanges, int nevents,
+    struct kevent_copyops *k_ops, const struct timespec *timeout);
+
+static int kern_kevent_fp(struct thread *td, struct file *fp, int nchanges,
+    int nevents, struct kevent_copyops *k_ops, const struct timespec *timeout);
+
+static
+#endif /* __rtems__ */
 int
 sys_kevent(struct thread *td, struct kevent_args *uap)
 {
@@ -1117,6 +1170,38 @@ kern_kevent_generic(struct thread *td, struct g_kevent_args *uap,
 
 	return (error);
 }
+#ifdef __rtems__
+__weak_reference(kevent, _kevent);
+
+int
+kevent(int kq, const struct kevent *changelist, int nchanges,
+    struct kevent *eventlist, int nevents,
+    const struct timespec *timeout)
+{
+	struct thread *td = rtems_bsd_get_curthread_or_null();
+	struct kevent_args ua = {
+		.fd = kq,
+		.changelist = changelist,
+		.nchanges = nchanges,
+		.eventlist = eventlist,
+		.nevents = nevents,
+		.timeout = timeout
+	};
+	int error;
+
+	if (td != NULL) {
+		error = sys_kevent(td, &ua);
+	} else {
+		error = ENOMEM;
+	}
+
+	if (error == 0) {
+		return td->td_retval[0];
+	} else {
+		rtems_set_errno_and_return_minus_one(error);
+	}
+}
+#endif /* __rtems__ */
 
 /*
  * Copy 'count' items into the destination list pointed to by uap->eventlist.
@@ -1430,7 +1515,6 @@ kqueue_register(struct kqueue *kq, struct kevent *kev, struct thread *td,
 	struct file *fp;
 #else /* __rtems__ */
 	rtems_libio_t *fp;
-	struct file *bsd_fp;
 #endif /* __rtems__ */
 	struct knote *kn, *tkn;
 	struct knlist *knl;
@@ -1509,8 +1593,7 @@ findkn:
 #ifndef __rtems__
 		if (fp->f_type == DTYPE_KQUEUE) {
 #else /* __rtems__ */
-		bsd_fp = rtems_bsd_iop_to_file(fp);
-		if (bsd_fp != NULL && bsd_fp->f_type == DTYPE_KQUEUE) {
+		if (fp->pathinfo.handlers == &kqueueops) {
 #endif /* __rtems__ */
 			/*
 			 * If we add some intelligence about what we are doing,
@@ -1519,11 +1602,7 @@ findkn:
 			 * getting both the knlist lock and the kq lock since
 			 * they are the same thing.
 			 */
-#ifndef __rtems__
 			if (fp->f_data == kq) {
-#else /* __rtems__ */
-			if (bsd_fp->f_data == kq) {
-#endif /* __rtems__ */
 				error = EINVAL;
 				goto done;
 			}
@@ -1736,7 +1815,11 @@ kqueue_acquire(struct file *fp, struct kqueue **kqp)
 	error = 0;
 
 	kq = fp->f_data;
+#ifndef __rtems__
 	if (fp->f_type != DTYPE_KQUEUE || kq == NULL)
+#else /* __rtems__ */
+	if (fp->pathinfo.handlers != &kqueueops || kq == NULL)
+#endif /* __rtems__ */
 		return (EBADF);
 	*kqp = kq;
 	KQ_LOCK(kq);
@@ -2077,6 +2160,7 @@ done_nl:
 	return (error);
 }
 
+#ifndef __rtems__
 /*ARGSUSED*/
 static int
 kqueue_ioctl(struct file *fp, u_long cmd, void *data,
@@ -2124,6 +2208,7 @@ kqueue_ioctl(struct file *fp, u_long cmd, void *data,
 
 	return (ENOTTY);
 }
+#endif /* __rtems__ */
 
 /*ARGSUSED*/
 static int
@@ -2151,14 +2236,38 @@ kqueue_poll(struct file *fp, int events, struct ucred *active_cred,
 	KQ_UNLOCK(kq);
 	return (revents);
 }
+#ifdef __rtems__
+static int
+rtems_bsd_kqueue_poll(rtems_libio_t *iop, int events)
+{
+	struct thread *td = rtems_bsd_get_curthread_or_null();
+	int error;
+
+	if (td != NULL) {
+		error = kqueue_poll(iop, events, NULL, td);
+	} else {
+		error = ENOMEM;
+	}
+
+	return error;
+}
+#endif /* __rtems__ */
 
 /*ARGSUSED*/
+#ifndef __rtems__
 static int
 kqueue_stat(struct file *fp, struct stat *st, struct ucred *active_cred,
 	struct thread *td)
 {
 
 	bzero((void *)st, sizeof *st);
+#else /* __rtems__ */
+static int
+rtems_bsd_kqueue_stat(const rtems_filesystem_location_info_t *loc,
+    struct stat *st)
+{
+	(void) loc;
+#endif /* __rtems__ */
 	/*
 	 * We no longer return kq_count because the unlocked value is useless.
 	 * If you spent all this time getting the count, why not spend your
@@ -2237,8 +2346,10 @@ static void
 kqueue_destroy(struct kqueue *kq)
 {
 
+#ifndef __rtems__
 	KASSERT(kq->kq_fdp == NULL,
 	    ("kqueue still attached to a file descriptor"));
+#endif /* __rtems__ */
 	seldrain(&kq->kq_sel);
 	knlist_destroy(&kq->kq_sel.si_note);
 	mtx_destroy(&kq->kq_lock);
@@ -2298,7 +2409,24 @@ kqueue_close(struct file *fp, struct thread *td)
 
 	return (0);
 }
+#ifdef __rtems__
+static int
+rtems_bsd_kqueue_close(rtems_libio_t *iop)
+{
+	struct thread *td = rtems_bsd_get_curthread_or_null();
+	int error;
+
+	if (td != NULL) {
+		error = kqueue_close(iop, td);
+	} else {
+		error = ENOMEM;
+	}
+
+	return rtems_bsd_error_to_status_and_errno(error);
+}
+#endif /* __rtems__ */
 
+#ifndef __rtems__
 static int
 kqueue_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
 {
@@ -2306,6 +2434,7 @@ kqueue_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
 	kif->kf_type = KF_TYPE_KQUEUE;
 	return (0);
 }
+#endif /* __rtems__ */
 
 static void
 kqueue_wakeup(struct kqueue *kq)
@@ -2860,3 +2989,23 @@ noacquire:
 	fdrop(fp, td);
 	return (error);
 }
+#ifdef __rtems__
+static const rtems_filesystem_file_handlers_r kqueueops = {
+	.open_h = rtems_filesystem_default_open,
+	.close_h = rtems_bsd_kqueue_close,
+	.read_h = rtems_filesystem_default_read,
+	.write_h = rtems_filesystem_default_write,
+	.ioctl_h = rtems_filesystem_default_ioctl,
+	.lseek_h = rtems_filesystem_default_lseek,
+	.fstat_h = rtems_bsd_kqueue_stat,
+	.ftruncate_h = rtems_filesystem_default_ftruncate,
+	.fsync_h = rtems_filesystem_default_fsync_or_fdatasync,
+	.fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
+	.fcntl_h = rtems_filesystem_default_fcntl,
+	.poll_h = rtems_bsd_kqueue_poll,
+	.kqfilter_h = rtems_bsd_kqueue_kqfilter,
+	.readv_h = rtems_filesystem_default_readv,
+	.writev_h = rtems_filesystem_default_writev,
+	.mmap_h = rtems_filesystem_default_mmap
+};
+#endif /* __rtems__ */
diff --git a/freebsd/sys/sys/eventvar.h b/freebsd/sys/sys/eventvar.h
index 1ed6e9fc..8afaa1aa 100644
--- a/freebsd/sys/sys/eventvar.h
+++ b/freebsd/sys/sys/eventvar.h
@@ -48,7 +48,9 @@ struct kqueue {
 	int		kq_count;		/* number of pending events */
 	struct		selinfo kq_sel;
 	struct		sigio *kq_sigio;
+#ifndef __rtems__
 	struct		filedesc *kq_fdp;
+#endif /* __rtems__ */
 	int		kq_state;
 #define KQ_SEL		0x01
 #define KQ_SLEEP	0x02
diff --git a/freebsd/sys/sys/sysproto.h b/freebsd/sys/sys/sysproto.h
index 1c1891de..8e915185 100644
--- a/freebsd/sys/sys/sysproto.h
+++ b/freebsd/sys/sys/sysproto.h
@@ -2133,9 +2133,7 @@ int	sys_extattr_delete_file(struct thread *, struct extattr_delete_file_args *);
 int	sys_aio_waitcomplete(struct thread *, struct aio_waitcomplete_args *);
 int	sys_getresuid(struct thread *, struct getresuid_args *);
 int	sys_getresgid(struct thread *, struct getresgid_args *);
-#endif /* __rtems__ */
 int	sys_kqueue(struct thread *, struct kqueue_args *);
-#ifndef __rtems__
 int	sys_extattr_set_fd(struct thread *, struct extattr_set_fd_args *);
 int	sys_extattr_get_fd(struct thread *, struct extattr_get_fd_args *);
 int	sys_extattr_delete_fd(struct thread *, struct extattr_delete_fd_args *);
@@ -2298,9 +2296,7 @@ int	sys_fstatfs(struct thread *, struct fstatfs_args *);
 int	sys_getfsstat(struct thread *, struct getfsstat_args *);
 int	sys_fhstatfs(struct thread *, struct fhstatfs_args *);
 int	sys_mknodat(struct thread *, struct mknodat_args *);
-#endif /* __rtems__ */
 int	sys_kevent(struct thread *, struct kevent_args *);
-#ifndef __rtems__
 int	sys_cpuset_getdomain(struct thread *, struct cpuset_getdomain_args *);
 int	sys_cpuset_setdomain(struct thread *, struct cpuset_setdomain_args *);
 int	sys_getrandom(struct thread *, struct getrandom_args *);
diff --git a/rtemsbsd/rtems/rtems-bsd-syscall-api.c b/rtemsbsd/rtems/rtems-bsd-syscall-api.c
index ba8a6b60..8a60afc1 100644
--- a/rtemsbsd/rtems/rtems-bsd-syscall-api.c
+++ b/rtemsbsd/rtems/rtems-bsd-syscall-api.c
@@ -383,54 +383,6 @@ getsockopt(int socket, int level, int option_name,
 	return rtems_bsd_error_to_status_and_errno(error);
 }
 
-int
-kqueue(void)
-{
-	struct thread *td = rtems_bsd_get_curthread_or_null();
-	struct kqueue_args ua = {};
-	int error;
-	if (RTEMS_BSD_SYSCALL_TRACE) {
-		printf("bsd: sys: kqueue:\n");
-	}
-	if (td == NULL) {
-		return rtems_bsd_error_to_status_and_errno(ENOMEM);
-	}
-	error = sys_kqueue(td, &ua);
-	if (error != 0) {
-		return rtems_bsd_error_to_status_and_errno(error);
-	}
-	return (td->td_retval[0]);
-}
-
-__weak_reference(kevent, _kevent);
-
-int
-kevent(int kq, const struct kevent *changelist, int nchanges,
-    struct kevent *eventlist, int nevents, const struct timespec *timeout)
-{
-	struct thread *td = rtems_bsd_get_curthread_or_null();
-	struct kevent_args ua;
-	int ffd;
-	int error;
-	if (RTEMS_BSD_SYSCALL_TRACE) {
-		printf("bsd: sys: kevent: %d\n", kq);
-	}
-	if (td == NULL) {
-		return rtems_bsd_error_to_status_and_errno(ENOMEM);
-	}
-	ua.fd = kq;
-	ua.changelist = changelist;
-	ua.nchanges = nchanges;
-	ua.eventlist = eventlist;
-	ua.nevents = nevents;
-	ua.timeout = timeout;
-	error = sys_kevent(td, &ua);
-	if (error != 0) {
-		return rtems_bsd_error_to_status_and_errno(error);
-	}
-	return td->td_retval[0];
-}
-
 int
 listen(int socket, int backlog)
 {
diff --git a/testsuite/syscalls01/test_main.c b/testsuite/syscalls01/test_main.c
index 3cfda667..dd2caebc 100644
--- a/testsuite/syscalls01/test_main.c
+++ b/testsuite/syscalls01/test_main.c
@@ -1598,12 +1598,12 @@ test_kqueue_unsupported_ops(void)
 	errno = 0;
 	n = read(kq, &buf[0], sizeof(buf));
 	assert(n == -1);
-	assert(errno == EOPNOTSUPP);
+	assert(errno == ENOTSUP);
 
 	errno = 0;
 	n = write(kq, &buf[0], sizeof(buf));
 	assert(n == -1);
-	assert(errno == EOPNOTSUPP);
+	assert(errno == ENOTSUP);
 
 	errno = 0;
 	rv = ioctl(kq, 0);
@@ -1643,8 +1643,7 @@ no_mem_kqueue_fstat(int fd)
 	int rv;
 
 	rv = fstat(fd, &st);
-	assert(rv == -1);
-	assert(errno == ENOMEM);
+	assert(rv == 0);
 }
 
 static void
-- 
2.35.3



More information about the devel mailing list