summaryrefslogtreecommitdiffstats
path: root/sys/sys/event.h
diff options
context:
space:
mode:
authorvisa <visa@openbsd.org>2020-12-20 12:54:05 +0000
committervisa <visa@openbsd.org>2020-12-20 12:54:05 +0000
commit88864a095289d33e87edd0c195ec74839938114c (patch)
tree827f9da5605946319ef8015b4ddc56158db68376 /sys/sys/event.h
parentFix EDNS Client Subnet option (+subnet=) (diff)
downloadwireguard-openbsd-88864a095289d33e87edd0c195ec74839938114c.tar.xz
wireguard-openbsd-88864a095289d33e87edd0c195ec74839938114c.zip
Introduce klistops
This patch extends struct klist with a callback descriptor and an argument. The main purpose of this is to let the kqueue subsystem assert when a klist should be locked, and operate the klist lock in klist_invalidate(). Access to a knote list of a kqueue-monitored object has to be serialized somehow. Because the object often has a lock for protecting its state, and because the object often acquires this lock at the latest in its f_event callback function, it makes sense to use this lock also for the knote lists. The existing uses of NOTE_SUBMIT already show a pattern that is likely to become more prevalent. There could be an embedded lock in klist. However, such a lock would be redundant in many cases. The code cannot rely on a single lock type (mutex, rwlock, something else) because the needs of monitored objects vary. In addition, an embedded lock would introduce new lock order constraints. Note that the patch does not rule out use of dedicated klist locks. The patch introduces a way to associate lock operations with a klist. The caller can provide a custom implementation, or use a ready-made interface with a mutex or rwlock. For compatibility with old code, the new code falls back to using the kernel lock if no specific klist initialization has been done. The existing code already relies on implicit initialization of klist. Sadly, this change increases the size of struct klist. dlg@ thinks this is not fatal, though. OK mpi@
Diffstat (limited to 'sys/sys/event.h')
-rw-r--r--sys/sys/event.h18
1 files changed, 17 insertions, 1 deletions
diff --git a/sys/sys/event.h b/sys/sys/event.h
index 916ddac75a6..c8160f4cc55 100644
--- a/sys/sys/event.h
+++ b/sys/sys/event.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: event.h,v 1.50 2020/12/18 16:10:58 visa Exp $ */
+/* $OpenBSD: event.h,v 1.51 2020/12/20 12:54:05 visa Exp $ */
/*-
* Copyright (c) 1999,2000,2001 Jonathan Lemon <jlemon@FreeBSD.org>
@@ -127,11 +127,15 @@ struct kevent {
* programs which pull in <sys/proc.h> or <sys/selinfo.h>.
*/
#include <sys/queue.h>
+
+struct klistops;
struct knote;
SLIST_HEAD(knlist, knote);
struct klist {
struct knlist kl_list;
+ const struct klistops *kl_ops;
+ void *kl_arg;
};
#ifdef _KERNEL
@@ -200,6 +204,12 @@ struct knote {
#define kn_fp kn_ptr.p_fp
};
+struct klistops {
+ void (*klo_assertlk)(void *);
+ int (*klo_lock)(void *);
+ void (*klo_unlock)(void *, int);
+};
+
struct kqueue_scan_state {
struct kqueue *kqs_kq; /* kqueue of this scan */
struct knote kqs_start; /* start marker */
@@ -209,7 +219,9 @@ struct kqueue_scan_state {
* in queue */
};
+struct mutex;
struct proc;
+struct rwlock;
struct timespec;
extern const struct filterops sig_filtops;
@@ -229,6 +241,10 @@ extern void kqueue_scan_finish(struct kqueue_scan_state *);
extern void kqueue_purge(struct proc *, struct kqueue *);
extern int filt_seltrue(struct knote *kn, long hint);
extern int seltrue_kqfilter(dev_t, struct knote *);
+extern void klist_init(struct klist *, const struct klistops *, void *);
+extern void klist_init_mutex(struct klist *, struct mutex *);
+extern void klist_init_rwlock(struct klist *, struct rwlock *);
+extern void klist_free(struct klist *);
extern void klist_insert(struct klist *, struct knote *);
extern void klist_remove(struct klist *, struct knote *);
extern int klist_empty(struct klist *);