[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