diff options
author | 2017-11-04 14:13:53 +0000 | |
---|---|---|
committer | 2017-11-04 14:13:53 +0000 | |
commit | 290a836d36de7cb20c274caa66f9cbc92c591330 (patch) | |
tree | 8e7a6ab55184bcee638aac902590edc4b82cbed3 /sys/miscfs | |
parent | fuse_loop_mt() isn't implemented so return an error value. (diff) | |
download | wireguard-openbsd-290a836d36de7cb20c274caa66f9cbc92c591330.tar.xz wireguard-openbsd-290a836d36de7cb20c274caa66f9cbc92c591330.zip |
Make it possible for multiple threads to enter kqueue_scan() in parallel.
This is a requirement to use a sleeping lock inside kqueue filters.
It is now possible, but not recommended, to sleep inside ``f_event''.
Threads iterating over the list of pending events are now recognizing
and skipping other threads' markers. knote_acquire() and knote_release()
must be used to "own" a knote to make sure no other thread is sleeping
with a reference on it.
Acquire and marker logic taken from DragonFly but the KERNEL_LOCK()
is still serializing the execution of the kqueue code.
This also enable the NET_LOCK() in socket filters.
Tested by abieber@ & juanfra@, run by naddy@ in a bulk, ok visa@, bluhm@
Diffstat (limited to 'sys/miscfs')
-rw-r--r-- | sys/miscfs/fifofs/fifo_vnops.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/sys/miscfs/fifofs/fifo_vnops.c b/sys/miscfs/fifofs/fifo_vnops.c index 7502183f931..0f2077538a3 100644 --- a/sys/miscfs/fifofs/fifo_vnops.c +++ b/sys/miscfs/fifofs/fifo_vnops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fifo_vnops.c,v 1.58 2017/07/24 15:07:39 mpi Exp $ */ +/* $OpenBSD: fifo_vnops.c,v 1.59 2017/11/04 14:13:53 mpi Exp $ */ /* $NetBSD: fifo_vnops.c,v 1.18 1996/03/16 23:52:42 christos Exp $ */ /* @@ -545,8 +545,10 @@ int filt_fiforead(struct knote *kn, long hint) { struct socket *so = (struct socket *)kn->kn_hook; - int rv; + int s, rv; + if (!(hint & NOTE_SUBMIT)) + s = solock(so); kn->kn_data = so->so_rcv.sb_cc; if (so->so_state & SS_CANTRCVMORE) { kn->kn_flags |= EV_EOF; @@ -555,6 +557,8 @@ filt_fiforead(struct knote *kn, long hint) kn->kn_flags &= ~EV_EOF; rv = (kn->kn_data > 0); } + if (!(hint & NOTE_SUBMIT)) + sounlock(s); return (rv); } @@ -573,8 +577,10 @@ int filt_fifowrite(struct knote *kn, long hint) { struct socket *so = (struct socket *)kn->kn_hook; - int rv; + int s, rv; + if (!(hint & NOTE_SUBMIT)) + s = solock(so); kn->kn_data = sbspace(so, &so->so_snd); if (so->so_state & SS_CANTSENDMORE) { kn->kn_flags |= EV_EOF; @@ -583,6 +589,8 @@ filt_fifowrite(struct knote *kn, long hint) kn->kn_flags &= ~EV_EOF; rv = (kn->kn_data >= so->so_snd.sb_lowat); } + if (!(hint & NOTE_SUBMIT)) + sounlock(s); return (rv); } |