Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys - Define a new filterops flag FILTEROP_MPSAFE, which sta...
details: https://anonhg.NetBSD.org/src/rev/23ee4531f851
branches: trunk
changeset: 1023777:23ee4531f851
user: thorpej <thorpej%NetBSD.org@localhost>
date: Sun Sep 26 03:12:50 2021 +0000
description:
- Define a new filterops flag FILTEROP_MPSAFE, which states that the
kqueue filter does not require the KERNEL_LOCK to be held.
- Add wrappers around the calls into the filterops that take care of
the locking requirements.
No functional change, since no filterops yet define FILTEROP_MPSAFE.
diffstat:
sys/kern/kern_event.c | 102 +++++++++++++++++++++++++++++++++++++++----------
sys/sys/event.h | 3 +-
2 files changed, 83 insertions(+), 22 deletions(-)
diffs (190 lines):
diff -r a3b44f38b442 -r 23ee4531f851 sys/kern/kern_event.c
--- a/sys/kern/kern_event.c Sun Sep 26 01:28:43 2021 +0000
+++ b/sys/kern/kern_event.c Sun Sep 26 03:12:50 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_event.c,v 1.121 2021/09/26 01:16:10 thorpej Exp $ */
+/* $NetBSD: kern_event.c,v 1.122 2021/09/26 03:12:50 thorpej Exp $ */
/*-
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -59,7 +59,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_event.c,v 1.121 2021/09/26 01:16:10 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_event.c,v 1.122 2021/09/26 03:12:50 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -143,6 +143,12 @@
.f_event = filt_proc,
};
+/*
+ * file_filtops is not marked MPSAFE because it's going to call
+ * fileops::fo_kqfilter(), which might not be. That function,
+ * however, will override the knote's filterops, and thus will
+ * inherit the MPSAFE-ness of the back-end at that time.
+ */
static const struct filterops file_filtops = {
.f_flags = FILTEROP_ISFD,
.f_attach = filt_fileattach,
@@ -241,6 +247,69 @@
static krwlock_t kqueue_filter_lock; /* lock on filter lists */
static kmutex_t kqueue_misc_lock; /* miscellaneous */
+static int
+filter_attach(struct knote *kn)
+{
+ int rv;
+
+ KASSERT(kn->kn_fop != NULL);
+ KASSERT(kn->kn_fop->f_attach != NULL);
+
+ /*
+ * N.B. that kn->kn_fop may change as the result of calling
+ * f_attach().
+ */
+ if (kn->kn_fop->f_flags & FILTEROP_MPSAFE) {
+ rv = kn->kn_fop->f_attach(kn);
+ } else {
+ KERNEL_LOCK(1, NULL);
+ rv = kn->kn_fop->f_attach(kn);
+ KERNEL_UNLOCK_ONE(NULL);
+ }
+
+ return rv;
+}
+
+static void
+filter_detach(struct knote *kn)
+{
+ KASSERT(kn->kn_fop != NULL);
+ KASSERT(kn->kn_fop->f_detach != NULL);
+
+ if (kn->kn_fop->f_flags & FILTEROP_MPSAFE) {
+ kn->kn_fop->f_detach(kn);
+ } else {
+ KERNEL_LOCK(1, NULL);
+ kn->kn_fop->f_detach(kn);
+ KERNEL_UNLOCK_ONE(NULL);
+ }
+}
+
+static int
+filter_event(struct knote *kn, long hint)
+{
+ int rv;
+
+ KASSERT(kn->kn_fop != NULL);
+ KASSERT(kn->kn_fop->f_event != NULL);
+
+ if (kn->kn_fop->f_flags & FILTEROP_MPSAFE) {
+ rv = kn->kn_fop->f_event(kn, hint);
+ } else {
+ KERNEL_LOCK(1, NULL);
+ rv = kn->kn_fop->f_event(kn, hint);
+ KERNEL_UNLOCK_ONE(NULL);
+ }
+
+ return rv;
+}
+
+static void
+filter_touch(struct knote *kn, struct kevent *kev, long type)
+{
+ kn->kn_fop->f_touch(kn, kev, type);
+}
+
static kauth_listener_t kqueue_listener;
static int
@@ -1233,9 +1302,11 @@
}
SLIST_INSERT_HEAD(list, kn, kn_link);
- KERNEL_LOCK(1, NULL); /* XXXSMP */
- error = (*kfilter->filtops->f_attach)(kn);
- KERNEL_UNLOCK_ONE(NULL); /* XXXSMP */
+ /*
+ * N.B. kn->kn_fop may change as the result
+ * of filter_attach()!
+ */
+ error = filter_attach(kn);
if (error != 0) {
#ifdef DEBUG
struct proc *p = curlwp->l_proc;
@@ -1277,7 +1348,7 @@
if (!(kn->kn_fop->f_flags & FILTEROP_ISFD) &&
kn->kn_fop->f_touch != NULL) {
mutex_spin_enter(&kq->kq_lock);
- (*kn->kn_fop->f_touch)(kn, kev, EVENT_REGISTER);
+ filter_touch(kn, kev, EVENT_REGISTER);
mutex_spin_exit(&kq->kq_lock);
} else {
kn->kn_sfflags = kev->fflags;
@@ -1291,11 +1362,7 @@
* broken and does not return an error.
*/
done_ev_add:
- KASSERT(kn->kn_fop != NULL);
- KASSERT(kn->kn_fop->f_event != NULL);
- KERNEL_LOCK(1, NULL); /* XXXSMP */
- rv = (*kn->kn_fop->f_event)(kn, 0);
- KERNEL_UNLOCK_ONE(NULL); /* XXXSMP */
+ rv = filter_event(kn, 0);
if (rv)
knote_activate(kn);
@@ -1507,12 +1574,8 @@
}
if ((kn->kn_flags & EV_ONESHOT) == 0) {
mutex_spin_exit(&kq->kq_lock);
- KASSERT(kn->kn_fop != NULL);
- KASSERT(kn->kn_fop->f_event != NULL);
- KERNEL_LOCK(1, NULL); /* XXXSMP */
KASSERT(mutex_owned(&fdp->fd_lock));
- rv = (*kn->kn_fop->f_event)(kn, 0);
- KERNEL_UNLOCK_ONE(NULL); /* XXXSMP */
+ rv = filter_event(kn, 0);
mutex_spin_enter(&kq->kq_lock);
/* Re-poll if note was re-enqueued. */
if ((kn->kn_status & KN_QUEUED) != 0) {
@@ -1538,7 +1601,7 @@
kn->kn_fop->f_touch != NULL);
/* XXXAD should be got from f_event if !oneshot. */
if (touch) {
- (*kn->kn_fop->f_touch)(kn, kevp, EVENT_PROCESS);
+ filter_touch(kn, kevp, EVENT_PROCESS);
} else {
*kevp = kn->kn_kevent;
}
@@ -1872,10 +1935,7 @@
KASSERT(kn->kn_fop != NULL);
/* Remove from monitored object. */
if (dofop) {
- KASSERT(kn->kn_fop->f_detach != NULL);
- KERNEL_LOCK(1, NULL); /* XXXSMP */
- (*kn->kn_fop->f_detach)(kn);
- KERNEL_UNLOCK_ONE(NULL); /* XXXSMP */
+ filter_detach(kn);
}
/* Remove from descriptor table. */
diff -r a3b44f38b442 -r 23ee4531f851 sys/sys/event.h
--- a/sys/sys/event.h Sun Sep 26 01:28:43 2021 +0000
+++ b/sys/sys/event.h Sun Sep 26 03:12:50 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: event.h,v 1.41 2021/09/26 01:16:10 thorpej Exp $ */
+/* $NetBSD: event.h,v 1.42 2021/09/26 03:12:50 thorpej Exp $ */
/*-
* Copyright (c) 1999,2000,2001 Jonathan Lemon <jlemon%FreeBSD.org@localhost>
@@ -221,6 +221,7 @@
/* filterops flags */
#define FILTEROP_ISFD __BIT(0) /* ident == file descriptor */
+#define FILTEROP_MPSAFE __BIT(1) /* does not require KERNEL_LOCK */
/*
* Field locking:
Home |
Main Index |
Thread Index |
Old Index