This is similar to the socket & kqueue diff I just sent. Check for NOTE_SUBMIT hint in order to protect `so_state', `so_snd' and `so_rcv'.
ok? Index: miscfs//fifofs/fifo_vnops.c =================================================================== RCS file: /cvs/src/sys/miscfs/fifofs/fifo_vnops.c,v retrieving revision 1.54 diff -u -p -r1.54 fifo_vnops.c --- miscfs//fifofs/fifo_vnops.c 26 Jun 2017 09:32:31 -0000 1.54 +++ miscfs//fifofs/fifo_vnops.c 26 Jun 2017 14:07:29 -0000 @@ -527,14 +527,22 @@ int filt_fiforead(struct knote *kn, long hint) { struct socket *so = (struct socket *)kn->kn_hook; + 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; - return (1); + rv = 1; + } else { + kn->kn_flags &= ~EV_EOF; + rv = (kn->kn_data > 0); } - kn->kn_flags &= ~EV_EOF; - return (kn->kn_data > 0); + if (!(hint & NOTE_SUBMIT)) + sounlock(s); + + return (rv); } void @@ -551,12 +559,20 @@ int filt_fifowrite(struct knote *kn, long hint) { struct socket *so = (struct socket *)kn->kn_hook; + 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; - return (1); + rv = 1; + } else { + kn->kn_flags &= ~EV_EOF; + rv = (kn->kn_data >= so->so_snd.sb_lowat); } - kn->kn_flags &= ~EV_EOF; - return (kn->kn_data >= so->so_snd.sb_lowat); + if (!(hint & NOTE_SUBMIT)) + sounlock(s); + + return (rv); }